diff options
931 files changed, 16417 insertions, 7476 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index f249884cb1a0..458d1dfeadb8 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -115,6 +115,7 @@ aconfig_declarations_group { "framework-jobscheduler-job.flags-aconfig-java", "framework_graphics_flags_java_lib", "hwui_flags_java_lib", + "icu_exported_aconfig_flags_lib", "interaction_jank_monitor_flags_lib", "keystore2_flags_java-framework", "libcore_exported_aconfig_flags_lib", @@ -163,6 +164,14 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +// ICU +java_aconfig_library { + name: "icu_exported_aconfig_flags_lib", + aconfig_declarations: "icu_aconfig_flags", + mode: "exported", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Camera java_aconfig_library { name: "camera_platform_flags_core_java_lib", @@ -1409,6 +1418,7 @@ java_aconfig_library { // Content Capture aconfig_declarations { name: "android.view.contentcapture.flags-aconfig", + exportable: true, package: "android.view.contentcapture.flags", container: "system", srcs: ["core/java/android/view/contentcapture/flags/*.aconfig"], diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 60ba3b896a28..829442aed6ac 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -96,6 +96,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.UserPackage; +import android.content.res.Resources; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryStatsInternal; @@ -1784,7 +1785,8 @@ public class AlarmManagerService extends SystemService { mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mStartUserBeforeScheduledAlarms = Flags.startUserBeforeScheduledAlarms() - && UserManager.supportsMultipleUsers(); + && UserManager.supportsMultipleUsers() && Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_allowAlarmsOnStoppedUsers); if (mStartUserBeforeScheduledAlarms) { mUserWakeupStore = new UserWakeupStore(); mUserWakeupStore.init(); diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index a949ff5a331b..787fdee6ee16 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -1023,7 +1023,6 @@ stubs_defaults { api_levels_annotations_enabled: true, api_levels_annotations_dirs: [ "sdk-dir", - "api-versions-jars-dir", ], } diff --git a/cmds/am/am.sh b/cmds/am/am.sh index 54c2d394be2c..76ec214cb446 100755 --- a/cmds/am/am.sh +++ b/cmds/am/am.sh @@ -1,5 +1,8 @@ #!/system/bin/sh +# set to top-app process group +settaskprofile $$ SCHED_SP_TOP_APP >/dev/null 2>&1 || true + if [ "$1" != "instrument" ] ; then cmd activity "$@" else diff --git a/cmds/uinput/README.md b/cmds/uinput/README.md index 6138388b30c7..5734c847be87 100644 --- a/cmds/uinput/README.md +++ b/cmds/uinput/README.md @@ -59,7 +59,7 @@ Register a new uinput device | `name` | string | Device name | | `vid` | 16-bit integer | Vendor ID | | `pid` | 16-bit integer | Product ID | -| `bus` | string | Bus that device should use | +| `bus` | string | The bus to report | | `port` | string | `phys` value to report | | `configuration` | object array | uinput device configuration| | `ff_effects_max` | integer | `ff_effects_max` value | @@ -68,8 +68,11 @@ Register a new uinput device `id` is used for matching the subsequent commands to a specific device to avoid ambiguity when multiple devices are registered. -`bus` is used to determine how the uinput device is connected to the host. The options are `"usb"` -and `"bluetooth"`. +`bus` specifies the bus that the kernel should report the device as being connected to. The most +common values are `"usb"` and `"bluetooth"`, but any bus with a `BUS_…` constant in the [Linux +kernel's input.h][input.h] can be specified using the part of its identifier after `BUS_`. For +example, to specify the SPI bus type (`BUS_SPI` in the kernel header), use `"spi"` (or `"SPI"`, +since it's case-insensitive). Device configuration is used to configure the uinput device. The `type` field provides a `UI_SET_*` control code as an integer value or a string label (e.g. `"UI_SET_EVBIT"`), and data is a vector of @@ -137,6 +140,7 @@ Example: } ``` +[input.h]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/third_party/kernel/upstream/include/uapi/linux/input.h?q=BUS_ [struct input_absinfo]: https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/kernel/uapi/linux/input.h?q=%22struct%20input_absinfo%22 ##### Waiting for registration diff --git a/core/api/current.txt b/core/api/current.txt index 19f68eb0c787..26c64bd7adbc 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -10249,23 +10249,23 @@ package android.companion.virtual { public final class VirtualDevice implements android.os.Parcelable { method public int describeContents(); method public int getDeviceId(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @NonNull public int[] getDisplayIds(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public CharSequence getDisplayName(); + method @NonNull public int[] getDisplayIds(); + method @Nullable public CharSequence getDisplayName(); method @Nullable public String getName(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public String getPersistentDeviceId(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomSensorSupport(); + method @Nullable public String getPersistentDeviceId(); + method public boolean hasCustomSensorSupport(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.VirtualDevice> CREATOR; } public final class VirtualDeviceManager { - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public android.companion.virtual.VirtualDevice getVirtualDevice(int); + method @Nullable public android.companion.virtual.VirtualDevice getVirtualDevice(int); method @NonNull public java.util.List<android.companion.virtual.VirtualDevice> getVirtualDevices(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public void registerVirtualDeviceListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public void unregisterVirtualDeviceListener(@NonNull android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener); + method public void registerVirtualDeviceListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener); + method public void unregisterVirtualDeviceListener(@NonNull android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener); } - @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public static interface VirtualDeviceManager.VirtualDeviceListener { + public static interface VirtualDeviceManager.VirtualDeviceListener { method public default void onVirtualDeviceClosed(int); method public default void onVirtualDeviceCreated(int); } diff --git a/core/api/system-current.txt b/core/api/system-current.txt index ae5542be7548..15ae79e34061 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1290,9 +1290,7 @@ package android.app { public class WallpaperManager { method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void clearWallpaper(int, int); - method @FlaggedApi("android.app.customization_packs_apis") public static int getOrientation(@NonNull android.graphics.Point); method @FloatRange(from=0.0f, to=1.0f) @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount(); - method @FlaggedApi("android.app.customization_packs_apis") @Nullable public android.os.ParcelFileDescriptor getWallpaperFile(int, boolean); method @FlaggedApi("android.app.live_wallpaper_content_handling") @Nullable @RequiresPermission(android.Manifest.permission.READ_WALLPAPER_INTERNAL) public android.app.wallpaper.WallpaperInstance getWallpaperInstance(int); method public void setDisplayOffset(android.os.IBinder, int, int); method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull android.util.SparseArray<android.graphics.Rect>, boolean, int) throws java.io.IOException; @@ -1301,10 +1299,6 @@ package android.app { method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(allOf={android.Manifest.permission.SET_WALLPAPER_COMPONENT, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional=true) public boolean setWallpaperComponentWithDescription(@NonNull android.app.wallpaper.WallpaperDescription, int); method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponentWithFlags(@NonNull android.content.ComponentName, int); method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public void setWallpaperDimAmount(@FloatRange(from=0.0f, to=1.0f) float); - field @FlaggedApi("android.app.customization_packs_apis") public static final int ORIENTATION_LANDSCAPE = 1; // 0x1 - field @FlaggedApi("android.app.customization_packs_apis") public static final int ORIENTATION_PORTRAIT = 0; // 0x0 - field @FlaggedApi("android.app.customization_packs_apis") public static final int ORIENTATION_SQUARE_LANDSCAPE = 3; // 0x3 - field @FlaggedApi("android.app.customization_packs_apis") public static final int ORIENTATION_SQUARE_PORTRAIT = 2; // 0x2 } } @@ -3171,6 +3165,11 @@ package android.app.wallpaper { method @NonNull public android.util.SparseArray<android.graphics.Rect> getCropHints(); } + public static final class WallpaperDescription.Builder { + method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>); + method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>); + } + } package android.app.wallpapereffectsgeneration { @@ -3399,8 +3398,8 @@ package android.companion.virtual { } public final class VirtualDevice implements android.os.Parcelable { - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomAudioInputSupport(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomCameraSupport(); + method public boolean hasCustomAudioInputSupport(); + method public boolean hasCustomCameraSupport(); } public final class VirtualDeviceManager { @@ -3452,7 +3451,7 @@ package android.companion.virtual { method @NonNull public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig); method @Deprecated @NonNull public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method public int getDeviceId(); - method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public String getPersistentDeviceId(); + method @Nullable public String getPersistentDeviceId(); method @NonNull public java.util.List<android.companion.virtual.sensor.VirtualSensor> getVirtualSensorList(); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public void goToSleep(); method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); @@ -3463,7 +3462,7 @@ package android.companion.virtual { method public void removeSoundEffectListener(@NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener); method public void setDevicePolicy(int, int); method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public void setDevicePolicy(int, int, int); - method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") public void setDisplayImePolicy(int, int); + method public void setDisplayImePolicy(int, int); method public void setShowPointerIcon(boolean); method public void unregisterIntentInterceptor(@NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public void wakeUp(); @@ -3482,7 +3481,7 @@ package android.companion.virtual { method public int getDevicePolicy(int); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public java.time.Duration getDimDuration(); method @Nullable public android.content.ComponentName getHomeComponent(); - method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") @Nullable public android.content.ComponentName getInputMethodComponent(); + method @Nullable public android.content.ComponentName getInputMethodComponent(); method public int getLockState(); method @Nullable public String getName(); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public java.time.Duration getScreenOffTimeout(); @@ -3521,7 +3520,7 @@ package android.companion.virtual { method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDevicePolicy(int, int); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDimDuration(@NonNull java.time.Duration); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setHomeComponent(@Nullable android.content.ComponentName); - method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setInputMethodComponent(@Nullable android.content.ComponentName); + method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setInputMethodComponent(@Nullable android.content.ComponentName); method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String); method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setScreenOffTimeout(@NonNull java.time.Duration); @@ -5325,7 +5324,7 @@ package android.hardware.display { method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration); method @RequiresPermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS) public void setBrightnessConfigurationForDisplay(@NonNull android.hardware.display.BrightnessConfiguration, @NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_SATURATION) public void setSaturationLevel(float); - field @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 128; // 0x80 + field public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 128; // 0x80 field public static final int VIRTUAL_DISPLAY_FLAG_STEAL_TOP_FOCUS_DISABLED = 65536; // 0x10000 field public static final int VIRTUAL_DISPLAY_FLAG_TRUSTED = 1024; // 0x400 } @@ -19044,7 +19043,7 @@ package android.view.displayhash { package android.view.inputmethod { public final class InputMethodInfo implements android.os.Parcelable { - method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") public boolean isVirtualDeviceOnly(); + method public boolean isVirtualDeviceOnly(); } public final class InputMethodManager { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index b118c7b6fed8..0126db70296c 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -508,7 +508,6 @@ package android.app { method @Nullable public android.graphics.Bitmap getBitmap(); method @Nullable public android.graphics.Bitmap getBitmapAsUser(int, boolean, int); method @FlaggedApi("com.android.window.flags.multi_crop") @NonNull @RequiresPermission(android.Manifest.permission.READ_WALLPAPER_INTERNAL) public java.util.List<android.graphics.Rect> getBitmapCrops(@NonNull java.util.List<android.graphics.Point>, int, boolean); - method @FlaggedApi("android.app.customization_packs_apis") @NonNull @RequiresPermission(android.Manifest.permission.READ_WALLPAPER_INTERNAL) public android.util.SparseArray<android.graphics.Rect> getBitmapCrops(int); method @FlaggedApi("com.android.window.flags.multi_crop") @NonNull public java.util.List<android.graphics.Rect> getBitmapCrops(@NonNull android.graphics.Point, @NonNull java.util.List<android.graphics.Point>, @Nullable java.util.Map<android.graphics.Point,android.graphics.Rect>); method public boolean isLockscreenLiveWallpaperEnabled(); method @Nullable public android.graphics.Rect peekBitmapDimensions(); @@ -882,15 +881,6 @@ package android.app.usage { } -package android.app.wallpaper { - - public static final class WallpaperDescription.Builder { - method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull java.util.Map<android.graphics.Point,android.graphics.Rect>); - method @NonNull public android.app.wallpaper.WallpaperDescription.Builder setCropHints(@NonNull android.util.SparseArray<android.graphics.Rect>); - } - -} - package android.appwidget { public class AppWidgetManager { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 4782205e3b21..220fbb5c16a6 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -26,8 +26,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.inMultiWindowMode; import static android.os.Process.myUid; -import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext; - import static java.lang.Character.MIN_VALUE; import android.Manifest; @@ -8999,12 +8997,11 @@ public class Activity extends ContextThemeWrapper Configuration config, String referrer, IVoiceInteractor voiceInteractor, Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken, IBinder shareableActivityToken, IBinder initialCallerInfoAccessToken) { - if (sandboxActivitySdkBasedContext()) { - // Sandbox activities extract a token from the intent's extra to identify the related - // SDK as part of overriding attachBaseContext, then it wraps the passed context in an - // SDK ContextWrapper, so mIntent has to be set before calling attachBaseContext. - mIntent = intent; - } + + // mIntent field hast to be set before calling attachBaseContext, as SDK Runtime activities + // extract a token from the intent's extra to identify the related SDK as part of overriding + // attachBaseContext. + mIntent = intent; attachBaseContext(context); mFragments.attachHost(null /*parent*/); @@ -9030,8 +9027,6 @@ public class Activity extends ContextThemeWrapper mShareableActivityToken = shareableActivityToken; mIdent = ident; mApplication = application; - //TODO(b/300059435): do not set the mIntent again as part of the flag clean up. - mIntent = intent; mReferrer = referrer; mComponent = intent.getComponent(); mTitle = title; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 717a2acb4b4a..2cfba4b8468f 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -41,7 +41,6 @@ import static android.window.ConfigurationHelper.shouldUpdateResources; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import static com.android.internal.os.SafeZipPathValidatorCallback.VALIDATE_ZIP_PATH_FOR_PATH_TRAVERSAL; -import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext; import android.annotation.NonNull; import android.annotation.Nullable; @@ -4072,9 +4071,7 @@ public final class ActivityThread extends ClientTransactionHandler r.activityInfo.targetActivity); } - boolean isSandboxActivityContext = - sandboxActivitySdkBasedContext() - && SdkSandboxActivityAuthority.isSdkSandboxActivityIntent( + boolean isSandboxActivityContext = SdkSandboxActivityAuthority.isSdkSandboxActivityIntent( mSystemContext, r.intent); boolean isSandboxedSdkContextUsed = false; ContextImpl activityBaseContext; @@ -4734,6 +4731,7 @@ public final class ActivityThread extends ClientTransactionHandler } private void reportSplashscreenViewShown(IBinder token, SplashScreenView view) { + Trace.instant(Trace.TRACE_TAG_VIEW, "reportSplashscreenViewShown"); ActivityClient.getInstance().reportSplashScreenAttached(token); synchronized (this) { if (mSplashScreenGlobal != null) { @@ -4751,10 +4749,32 @@ public final class ActivityThread extends ClientTransactionHandler final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction(); transaction.hide(startingWindowLeash); - decorView.getViewRootImpl().applyTransactionOnDraw(transaction); view.syncTransferSurfaceOnDraw(); - // Tell server we can remove the starting window - decorView.postOnAnimation(() -> reportSplashscreenViewShown(token, view)); + + if (com.android.window.flags.Flags.useRtFrameCallbackForSplashScreenTransfer() + && decorView.isHardwareAccelerated()) { + decorView.getViewRootImpl().registerRtFrameCallback( + new HardwareRenderer.FrameDrawingCallback() { + @Override + public void onFrameDraw(long frame) { } + @Override + public HardwareRenderer.FrameCommitCallback onFrameDraw( + int syncResult, long frame) { + return didProduceBuffer -> { + Trace.instant(Trace.TRACE_TAG_VIEW, "transferSplashscreenView"); + transaction.apply(); + // Tell server we can remove the starting window after frame commit. + decorView.postOnAnimation(() -> + reportSplashscreenViewShown(token, view)); + }; + } + }); + } else { + Trace.instant(Trace.TRACE_TAG_VIEW, "transferSplashscreenView_software"); + decorView.getViewRootImpl().applyTransactionOnDraw(transaction); + // Tell server we can remove the starting window after frame commit. + decorView.postOnAnimation(() -> reportSplashscreenViewShown(token, view)); + } } /** diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java index f34341fd14e1..3214bd8f01fc 100644 --- a/core/java/android/app/ApplicationStartInfo.java +++ b/core/java/android/app/ApplicationStartInfo.java @@ -729,6 +729,7 @@ public final class ApplicationStartInfo implements Parcelable { return 0; } + // LINT.IfChange(write_parcel) @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mStartupState); @@ -753,6 +754,7 @@ public final class ApplicationStartInfo implements Parcelable { dest.writeLong(mMonoticCreationTimeMs); dest.writeInt(mStartComponent); } + // LINT.ThenChange(:read_parcel) /** @hide */ public ApplicationStartInfo(long monotonicCreationTimeMs) { @@ -779,6 +781,7 @@ public final class ApplicationStartInfo implements Parcelable { } /** @hide */ + // LINT.IfChange(read_parcel) @VisibleForTesting public ApplicationStartInfo(@NonNull Parcel in) { mStartupState = in.readInt(); @@ -803,6 +806,7 @@ public final class ApplicationStartInfo implements Parcelable { mMonoticCreationTimeMs = in.readLong(); mStartComponent = in.readInt(); } + // LINT.ThenChange(:write_parcel) private static String intern(@Nullable String source) { return source != null ? source.intern() : null; @@ -835,6 +839,7 @@ public final class ApplicationStartInfo implements Parcelable { * @param fieldId Field Id of the ApplicationStartInfo as defined in the parent message * @hide */ + // LINT.IfChange(write_proto) public void writeToProto(ProtoOutputStream proto, long fieldId) throws IOException { final long token = proto.start(fieldId); proto.write(ApplicationStartInfoProto.PID, mPid); @@ -884,6 +889,7 @@ public final class ApplicationStartInfo implements Parcelable { proto.write(ApplicationStartInfoProto.START_COMPONENT, mStartComponent); proto.end(token); } + // LINT.ThenChange(:read_proto) /** * Read from a protocol buffer input stream. Protocol buffer message definition at {@link @@ -893,6 +899,7 @@ public final class ApplicationStartInfo implements Parcelable { * @param fieldId Field Id of the ApplicationStartInfo as defined in the parent message * @hide */ + // LINT.IfChange(read_proto) public void readFromProto(ProtoInputStream proto, long fieldId) throws IOException, WireTypeMismatchException, ClassNotFoundException { final long token = proto.start(fieldId); @@ -976,6 +983,7 @@ public final class ApplicationStartInfo implements Parcelable { } proto.end(token); } + // LINT.ThenChange(:write_proto) /** @hide */ public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, diff --git a/core/java/android/app/DisabledWallpaperManager.java b/core/java/android/app/DisabledWallpaperManager.java index 233dc75b810f..087bcd8620e4 100644 --- a/core/java/android/app/DisabledWallpaperManager.java +++ b/core/java/android/app/DisabledWallpaperManager.java @@ -177,13 +177,6 @@ final class DisabledWallpaperManager extends WallpaperManager { } @Override - @NonNull - public SparseArray<Rect> getBitmapCrops(int which) { - unsupported(); - return new SparseArray<>(); - } - - @Override public List<Rect> getBitmapCrops(@NonNull Point bitmapSize, @NonNull List<Point> displaySizes, @Nullable Map<Point, Rect> cropHints) { return unsupported(); diff --git a/core/java/android/app/DreamManager.java b/core/java/android/app/DreamManager.java index 4ac40a1f77b2..c597a9dcae7e 100644 --- a/core/java/android/app/DreamManager.java +++ b/core/java/android/app/DreamManager.java @@ -234,4 +234,19 @@ public class DreamManager { throw e.rethrowFromSystemServer(); } } + + /** + * Notifies dream manager of device postured state, which may affect dream enablement. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_ALLOW_DREAM_WHEN_POSTURED) + @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) + public void setDevicePostured(boolean isPostured) { + try { + mService.setDevicePostured(isPostured); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 1738a92b7672..4a78d01783f8 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -271,6 +271,6 @@ interface INotificationManager int[] getAllowedAdjustmentKeyTypes(); void setAssistantAdjustmentKeyTypeState(int type, boolean enabled); - int[] getAllowedAdjustmentKeyTypesForPackage(String pkg); - void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, boolean enabled); + String[] getTypeAdjustmentDeniedPackages(); + void setTypeAdjustmentForPackageState(String pkg, boolean enabled); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 3c37b449c3a8..93d751cb9402 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -6627,7 +6627,20 @@ public class Notification implements Parcelable */ @Deprecated public RemoteViews createContentView() { - return createContentView(false /* increasedheight */ ); + if (useExistingRemoteView(mN.contentView)) { + return fullyCustomViewRequiresDecoration(false /* fromStyle */) + ? minimallyDecoratedContentView(mN.contentView) : mN.contentView; + } else if (mStyle != null) { + final RemoteViews styleView = mStyle.makeContentView(); + if (styleView != null) { + return fullyCustomViewRequiresDecoration(true /* fromStyle */) + ? minimallyDecoratedContentView(styleView) : styleView; + } + } + StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) + .fillTextsFrom(this); + return applyStandardTemplate(getCollapsedBaseLayoutResource(), p, null /* result */); } // This code is executed on behalf of other apps' notifications, sometimes even by 3p apps, @@ -6688,33 +6701,6 @@ public class Notification implements Parcelable return standard; } - /** - * Construct a RemoteViews for the smaller content view. - * - * @param increasedHeight true if this layout be created with an increased height. Some - * styles may support showing more then just that basic 1U size - * and the system may decide to render important notifications - * slightly bigger even when collapsed. - * - * @hide - */ - public RemoteViews createContentView(boolean increasedHeight) { - if (useExistingRemoteView(mN.contentView)) { - return fullyCustomViewRequiresDecoration(false /* fromStyle */) - ? minimallyDecoratedContentView(mN.contentView) : mN.contentView; - } else if (mStyle != null) { - final RemoteViews styleView = mStyle.makeContentView(increasedHeight); - if (styleView != null) { - return fullyCustomViewRequiresDecoration(true /* fromStyle */) - ? minimallyDecoratedContentView(styleView) : styleView; - } - } - StandardTemplateParams p = mParams.reset() - .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) - .fillTextsFrom(this); - return applyStandardTemplate(getCollapsedBaseLayoutResource(), p, null /* result */); - } - private boolean useExistingRemoteView(RemoteViews customContent) { if (customContent == null) { return false; @@ -6850,48 +6836,13 @@ public class Notification implements Parcelable } /** - * Construct a RemoteViews for the final heads-up notification layout. - * - * @param increasedHeight true if this layout be created with an increased height. Some - * styles may support showing more then just that basic 1U size - * and the system may decide to render important notifications - * slightly bigger even when collapsed. - * - * @hide - */ - public RemoteViews createHeadsUpContentView(boolean increasedHeight) { - if (useExistingRemoteView(mN.headsUpContentView)) { - return fullyCustomViewRequiresDecoration(false /* fromStyle */) - ? minimallyDecoratedHeadsUpContentView(mN.headsUpContentView) - : mN.headsUpContentView; - } else if (mStyle != null) { - final RemoteViews styleView = mStyle.makeHeadsUpContentView(increasedHeight); - if (styleView != null) { - return fullyCustomViewRequiresDecoration(true /* fromStyle */) - ? minimallyDecoratedHeadsUpContentView(styleView) : styleView; - } - } else if (mActions.size() == 0) { - return null; - } - - // We only want at most a single remote input history to be shown here, otherwise - // the content would become squished. - StandardTemplateParams p = mParams.reset() - .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP) - .fillTextsFrom(this) - .setMaxRemoteInputHistory(1); - return applyStandardTemplateWithActions(getHeadsUpBaseLayoutResource(), p, - null /* result */); - } - - /** * Construct a RemoteViews for the final compact heads-up notification layout. * @hide */ public RemoteViews createCompactHeadsUpContentView() { // Don't show compact heads up for FSI notifications. if (mN.fullScreenIntent != null) { - return createHeadsUpContentView(/* increasedHeight= */ false); + return createHeadsUpContentView(); } if (mStyle != null) { @@ -6929,7 +6880,28 @@ public class Notification implements Parcelable */ @Deprecated public RemoteViews createHeadsUpContentView() { - return createHeadsUpContentView(false /* useIncreasedHeight */); + if (useExistingRemoteView(mN.headsUpContentView)) { + return fullyCustomViewRequiresDecoration(false /* fromStyle */) + ? minimallyDecoratedHeadsUpContentView(mN.headsUpContentView) + : mN.headsUpContentView; + } else if (mStyle != null) { + final RemoteViews styleView = mStyle.makeHeadsUpContentView(); + if (styleView != null) { + return fullyCustomViewRequiresDecoration(true /* fromStyle */) + ? minimallyDecoratedHeadsUpContentView(styleView) : styleView; + } + } else if (mActions.size() == 0) { + return null; + } + + // We only want at most a single remote input history to be shown here, otherwise + // the content would become squished. + StandardTemplateParams p = mParams.reset() + .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP) + .fillTextsFrom(this) + .setMaxRemoteInputHistory(1); + return applyStandardTemplateWithActions(getHeadsUpBaseLayoutResource(), p, + null /* result */); } /** @@ -8236,10 +8208,9 @@ public class Notification implements Parcelable * Construct a Style-specific RemoteViews for the collapsed notification layout. * The default implementation has nothing additional to add. * - * @param increasedHeight true if this layout be created with an increased height. * @hide */ - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { return null; } @@ -8254,10 +8225,9 @@ public class Notification implements Parcelable /** * Construct a Style-specific RemoteViews for the final HUN layout. * - * @param increasedHeight true if this layout be created with an increased height. * @hide */ - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { return null; } @@ -8543,9 +8513,9 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { if (mPictureIcon == null || !mShowBigPictureWhenCollapsed) { - return super.makeContentView(increasedHeight); + return super.makeContentView(); } StandardTemplateParams p = mBuilder.mParams.reset() @@ -8559,9 +8529,9 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { if (mPictureIcon == null || !mShowBigPictureWhenCollapsed) { - return super.makeHeadsUpContentView(increasedHeight); + return super.makeHeadsUpContentView(); } StandardTemplateParams p = mBuilder.mParams.reset() @@ -8792,35 +8762,6 @@ public class Notification implements Parcelable } /** - * @param increasedHeight true if this layout be created with an increased height. - * - * @hide - */ - @Override - public RemoteViews makeContentView(boolean increasedHeight) { - if (increasedHeight) { - ArrayList<Action> originalActions = mBuilder.mActions; - mBuilder.mActions = new ArrayList<>(); - RemoteViews remoteViews = makeExpandedContentView(); - mBuilder.mActions = originalActions; - return remoteViews; - } - return super.makeContentView(increasedHeight); - } - - /** - * @hide - */ - @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { - if (increasedHeight && mBuilder.mActions.size() > 0) { - // TODO(b/163626038): pass VIEW_TYPE_HEADS_UP? - return makeExpandedContentView(); - } - return super.makeHeadsUpContentView(increasedHeight); - } - - /** * @hide */ public RemoteViews makeExpandedContentView() { @@ -9404,7 +9345,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { // All messaging templates contain the actions ArrayList<Action> originalActions = mBuilder.mActions; try { @@ -9649,7 +9590,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { return makeMessagingView(StandardTemplateParams.VIEW_TYPE_HEADS_UP); } @@ -10484,7 +10425,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { return makeMediaContentView(null /* customContent */); } @@ -10500,7 +10441,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { return makeMediaContentView(null /* customContent */); } @@ -10913,7 +10854,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { return makeCallLayout(StandardTemplateParams.VIEW_TYPE_NORMAL); } @@ -10921,7 +10862,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { return makeCallLayout(StandardTemplateParams.VIEW_TYPE_HEADS_UP); } @@ -10932,7 +10873,7 @@ public class Notification implements Parcelable @Override public RemoteViews makeCompactHeadsUpContentView() { // Use existing heads up for call style. - return makeHeadsUpContentView(false); + return makeHeadsUpContentView(); } /** @@ -11701,7 +11642,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { final StandardTemplateParams p = mBuilder.mParams.reset() .viewType(StandardTemplateParams.VIEW_TYPE_NORMAL) .hideProgress(true) @@ -11713,7 +11654,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { final StandardTemplateParams p = mBuilder.mParams.reset() .viewType(StandardTemplateParams.VIEW_TYPE_HEADS_UP) .hideProgress(true) @@ -12192,7 +12133,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { return makeStandardTemplateWithCustomContent(mBuilder.mN.contentView); } @@ -12208,7 +12149,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { return makeDecoratedHeadsUpContentView(); } @@ -12328,7 +12269,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeContentView(boolean increasedHeight) { + public RemoteViews makeContentView() { return makeMediaContentView(mBuilder.mN.contentView); } @@ -12347,7 +12288,7 @@ public class Notification implements Parcelable * @hide */ @Override - public RemoteViews makeHeadsUpContentView(boolean increasedHeight) { + public RemoteViews makeHeadsUpContentView() { RemoteViews customContent = mBuilder.mN.headsUpContentView != null ? mBuilder.mN.headsUpContentView : mBuilder.mN.contentView; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 24f2495d8f09..e5d80de24f2b 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -2163,12 +2163,10 @@ public class NotificationManager { * @hide */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void setAssistantAdjustmentKeyTypeStateForPackage(@NonNull String pkg, - @Adjustment.Types int type, - boolean enabled) { + public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) { INotificationManager service = service(); try { - service.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); + service.setTypeAdjustmentForPackageState(pkg, enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 73ecc7199686..076f856635b5 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -19,7 +19,6 @@ package android.app; import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE; import static android.Manifest.permission.READ_WALLPAPER_INTERNAL; import static android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT; -import static android.app.Flags.FLAG_CUSTOMIZATION_PACKS_APIS; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; @@ -343,32 +342,24 @@ public class WallpaperManager { * Portrait orientation of most screens * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi public static final int ORIENTATION_PORTRAIT = 0; /** * Landscape orientation of most screens * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi public static final int ORIENTATION_LANDSCAPE = 1; /** * Portrait orientation with similar width and height (e.g. the inner screen of a foldable) * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi public static final int ORIENTATION_SQUARE_PORTRAIT = 2; /** * Landscape orientation with similar width and height (e.g. the inner screen of a foldable) * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi public static final int ORIENTATION_SQUARE_LANDSCAPE = 3; /** @@ -377,8 +368,6 @@ public class WallpaperManager { * @return the corresponding {@link ScreenOrientation}. * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi public static @ScreenOrientation int getOrientation(@NonNull Point screenSize) { float ratio = ((float) screenSize.x) / screenSize.y; // ratios between 3/4 and 4/3 are considered square @@ -1665,52 +1654,6 @@ public class WallpaperManager { } /** - * For the current user, if the wallpaper of the specified destination is an ImageWallpaper, - * return the custom crops of the wallpaper, that have been provided for example via - * {@link #setStreamWithCrops}. These crops are relative to the original bitmap. - * <p> - * This method helps apps that change wallpapers provide an undo option. Calling - * {@link #setStreamWithCrops(InputStream, SparseArray, boolean, int)} with this SparseArray and - * the current original bitmap file, that can be obtained with {@link #getWallpaperFile(int, - * boolean)} with {@code getCropped=false}, will exactly lead to the current wallpaper state. - * - * @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or {@link #FLAG_LOCK}. - * @return A map from {{@link #ORIENTATION_PORTRAIT}, {@link #ORIENTATION_LANDSCAPE}, - * {@link #ORIENTATION_SQUARE_PORTRAIT}, {{@link #ORIENTATION_SQUARE_LANDSCAPE}}} to - * Rect, representing the custom cropHints. The map can be empty and will only contains - * entries for screen orientations for which a custom crop was provided. If no custom - * crop is provided for an orientation, the system will infer the crop based on the - * custom crops of the other orientations; or center-align the full image if no custom - * crops are provided at all. - * <p> - * Return an empty map if the wallpaper is not an ImageWallpaper. Also return - * an empty map when called with which={@link #FLAG_LOCK} if there is a shared - * home + lock wallpaper. - * - * @hide - */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @TestApi - @RequiresPermission(READ_WALLPAPER_INTERNAL) - @NonNull - public SparseArray<Rect> getBitmapCrops(@SetWallpaperFlags int which) { - checkExactlyOneWallpaperFlagSet(which); - try { - Bundle bundle = sGlobals.mService.getCurrentBitmapCrops(which, mContext.getUserId()); - SparseArray<Rect> result = new SparseArray<>(); - if (bundle == null) return result; - for (String key : bundle.keySet()) { - int intKey = Integer.parseInt(key); - Rect rect = bundle.getParcelable(key, Rect.class); - result.put(intKey, rect); - } - return result; - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * For preview purposes. * Return how a bitmap of a given size would be cropped for a given list of display sizes, if * it was set as wallpaper via {@link #setBitmapWithCrops(Bitmap, Map, boolean, int)} or @@ -1955,8 +1898,6 @@ public class WallpaperManager { * which={@link #FLAG_LOCK} if there is a shared home + lock wallpaper. * @hide */ - @FlaggedApi(FLAG_CUSTOMIZATION_PACKS_APIS) - @SystemApi @Nullable public ParcelFileDescriptor getWallpaperFile(@SetWallpaperFlags int which, boolean getCropped) { return getWallpaperFile(which, mContext.getUserId(), getCropped); diff --git a/core/java/android/app/supervision/ISupervisionAppService.aidl b/core/java/android/app/supervision/ISupervisionAppService.aidl new file mode 100644 index 000000000000..207fab90d015 --- /dev/null +++ b/core/java/android/app/supervision/ISupervisionAppService.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.supervision; + +/** + * @hide + */ +interface ISupervisionAppService { + void onEnabled(); + void onDisabled(); +} diff --git a/core/java/android/app/supervision/SupervisionAppService.java b/core/java/android/app/supervision/SupervisionAppService.java new file mode 100644 index 000000000000..4530be5c270a --- /dev/null +++ b/core/java/android/app/supervision/SupervisionAppService.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.supervision; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +/** + * Base class for a service that the {@code android.app.role.RoleManager.ROLE_SYSTEM_SUPERVISION} + * role holder must implement. + * + * @hide + */ +public class SupervisionAppService extends Service { + private final ISupervisionAppService mBinder = new ISupervisionAppService.Stub() { + @Override + public void onEnabled() { + SupervisionAppService.this.onEnabled(); + } + + @Override + public void onDisabled() { + SupervisionAppService.this.onDisabled(); + } + }; + + @Override + public final IBinder onBind(Intent intent) { + return mBinder.asBinder(); + } + + /** + * Called when supervision is enabled. + */ + public void onEnabled() {} + + /** + * Called when supervision is disabled. + */ + public void onDisabled() {} +} diff --git a/core/java/android/app/supervision/SupervisionManager.java b/core/java/android/app/supervision/SupervisionManager.java index a5b58f968c27..92241f3634e8 100644 --- a/core/java/android/app/supervision/SupervisionManager.java +++ b/core/java/android/app/supervision/SupervisionManager.java @@ -34,6 +34,35 @@ public class SupervisionManager { private final Context mContext; private final ISupervisionManager mService; + /** + * Activity action: ask the human user to enable supervision for this user. Only the app that + * holds the {@code SYSTEM_SUPERVISION} role can launch this intent. + * + * <p>The intent must be invoked via {@link Activity#startActivityForResult} to receive the + * result of whether or not the user approved the action. If approved, the result will be {@link + * Activity#RESULT_OK}. + * + * <p>If supervision is already enabled, the operation will return a failure result. + * + * @hide + */ + public static final String ACTION_ENABLE_SUPERVISION = "android.app.action.ENABLE_SUPERVISION"; + + /** + * Activity action: ask the human user to disable supervision for this user. Only the app that + * holds the {@code SYSTEM_SUPERVISION} role can launch this intent. + * + * <p>The intent must be invoked via {@link Activity#startActivityForResult} to receive the + * result of whether or not the user approved the action. If approved, the result will be {@link + * Activity#RESULT_OK}. + * + * <p>If supervision is not enabled, the operation will return a failure result. + * + * @hide + */ + public static final String ACTION_DISABLE_SUPERVISION = + "android.app.action.DISABLE_SUPERVISION"; + /** @hide */ @UnsupportedAppUsage public SupervisionManager(Context context, ISupervisionManager service) { diff --git a/core/java/android/app/supervision/flags.aconfig b/core/java/android/app/supervision/flags.aconfig index 1b0353274fb9..4ee3a0360b43 100644 --- a/core/java/android/app/supervision/flags.aconfig +++ b/core/java/android/app/supervision/flags.aconfig @@ -32,3 +32,11 @@ flag { description: "Flag that deprecates supervision methods in DPM" bug: "382034839" } + +flag { + name: "enable_supervision_app_service" + is_exported: true + namespace: "supervision" + description: "Flag to enable the SupervisionAppService" + bug: "389123070" +} diff --git a/core/java/android/app/wallpaper.aconfig b/core/java/android/app/wallpaper.aconfig index be9e286f5eb7..7aba172fad79 100644 --- a/core/java/android/app/wallpaper.aconfig +++ b/core/java/android/app/wallpaper.aconfig @@ -24,14 +24,6 @@ flag { } flag { - name: "customization_packs_apis" - is_exported: true - namespace: "systemui" - description: "Move APIs related to bitmap and crops to @SystemApi." - bug: "372344184" -} - -flag { name: "accurate_wallpaper_downsampling" namespace: "systemui" description: "Accurate downsampling of wallpaper bitmap for high resolution images" diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java index 999a5da870ad..a13af7f1ddcd 100644 --- a/core/java/android/app/wallpaper/WallpaperDescription.java +++ b/core/java/android/app/wallpaper/WallpaperDescription.java @@ -19,9 +19,7 @@ package android.app.wallpaper; import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; import android.annotation.FlaggedApi; -import android.annotation.SuppressLint; import android.annotation.SystemApi; -import android.annotation.TestApi; import android.app.WallpaperInfo; import android.app.WallpaperManager; import android.app.WallpaperManager.ScreenOrientation; @@ -514,8 +512,7 @@ public final class WallpaperDescription implements Parcelable { * @hide */ @NonNull - @TestApi - @SuppressLint("MissingGetterMatchingBuilder") + @SystemApi public Builder setCropHints(@NonNull Map<Point, Rect> cropHints) { mCropHints = new SparseArray<>(); cropHints.forEach( @@ -531,8 +528,7 @@ public final class WallpaperDescription implements Parcelable { * @hide */ @NonNull - @TestApi - @SuppressLint("MissingGetterMatchingBuilder") + @SystemApi public Builder setCropHints(@NonNull SparseArray<Rect> cropHints) { mCropHints = cropHints; return this; diff --git a/core/java/android/companion/virtual/VirtualDevice.java b/core/java/android/companion/virtual/VirtualDevice.java index b9e9afea8893..8ef4224975bf 100644 --- a/core/java/android/companion/virtual/VirtualDevice.java +++ b/core/java/android/companion/virtual/VirtualDevice.java @@ -20,11 +20,9 @@ import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_SENSORS; -import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.companion.virtual.flags.Flags; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; @@ -34,8 +32,9 @@ import android.os.RemoteException; * Details of a particular virtual device. * * <p>Read-only device representation exposing the properties of an existing virtual device. + * + * @see VirtualDeviceManager#registerVirtualDeviceListener */ -// TODO(b/310912420): Link to VirtualDeviceManager#registerVirtualDeviceListener from the docs public final class VirtualDevice implements Parcelable { private final @NonNull IVirtualDevice mVirtualDevice; @@ -93,8 +92,8 @@ public final class VirtualDevice implements Parcelable { * per device. * * @see Context#createDeviceContext + * @see #getPersistentDeviceId() */ - // TODO(b/310912420): Link to #getPersistentDeviceId from the docs public int getDeviceId() { return mId; } @@ -111,7 +110,6 @@ public final class VirtualDevice implements Parcelable { * <p class="note">This identifier may not be unique across virtual devices, in case there are * more than one virtual devices corresponding to the same physical device. */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public @Nullable String getPersistentDeviceId() { return mPersistentId; } @@ -127,7 +125,6 @@ public final class VirtualDevice implements Parcelable { * Returns the human-readable name of the virtual device, if defined, which is suitable to be * shown in UI. */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public @Nullable CharSequence getDisplayName() { return mDisplayName; } @@ -138,7 +135,6 @@ public final class VirtualDevice implements Parcelable { * <p>The actual {@link android.view.Display} objects can be obtained by passing the returned * IDs to {@link android.hardware.display.DisplayManager#getDisplay(int)}.</p> */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public @NonNull int[] getDisplayIds() { try { return mVirtualDevice.getDisplayIds(); @@ -157,7 +153,6 @@ public final class VirtualDevice implements Parcelable { * @see Context#getDeviceId() * @see Context#createDeviceContext(int) */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public boolean hasCustomSensorSupport() { try { return mVirtualDevice.getDevicePolicy(POLICY_TYPE_SENSORS) == DEVICE_POLICY_CUSTOM; @@ -172,7 +167,6 @@ public final class VirtualDevice implements Parcelable { * @hide */ @SystemApi - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public boolean hasCustomAudioInputSupport() { try { return mVirtualDevice.hasCustomAudioInputSupport(); @@ -194,7 +188,6 @@ public final class VirtualDevice implements Parcelable { * @hide */ @SystemApi - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public boolean hasCustomCameraSupport() { try { return mVirtualDevice.getDevicePolicy(POLICY_TYPE_CAMERA) == DEVICE_POLICY_CUSTOM; diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 91ea673ab6f9..252db824c69f 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -223,10 +223,9 @@ public final class VirtualDeviceManager { * existing virtual devices.</p> * * <p>Note that if a virtual device is closed and becomes invalid, the returned objects will - * not be updated and may contain stale values.</p> + * not be updated and may contain stale values. Use a {@link VirtualDeviceListener} for real + * time updates of the availability of virtual devices.</p> */ - // TODO(b/310912420): Add "Use a VirtualDeviceListener for real time updates of the - // availability of virtual devices." in the note paragraph above with a link annotation. @NonNull public List<android.companion.virtual.VirtualDevice> getVirtualDevices() { if (mService == null) { @@ -253,7 +252,6 @@ public final class VirtualDeviceManager { * @return the virtual device with the requested ID, or {@code null} if no such device exists or * it has already been closed. */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) @Nullable public android.companion.virtual.VirtualDevice getVirtualDevice(int deviceId) { if (mService == null) { @@ -278,7 +276,6 @@ public final class VirtualDeviceManager { * @param listener The listener to add. * @see #unregisterVirtualDeviceListener */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public void registerVirtualDeviceListener( @NonNull @CallbackExecutor Executor executor, @NonNull VirtualDeviceListener listener) { @@ -306,7 +303,6 @@ public final class VirtualDeviceManager { * @param listener The listener to unregister. * @see #registerVirtualDeviceListener */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public void unregisterVirtualDeviceListener(@NonNull VirtualDeviceListener listener) { if (mService == null) { Log.w(TAG, "Failed to unregister listener; no virtual device manager service."); @@ -389,9 +385,9 @@ public final class VirtualDeviceManager { * @return the display name associated with the given persistent device ID, or {@code null} if * the persistent ID is invalid or does not correspond to a virtual device. * + * @see VirtualDevice#getPersistentDeviceId() * @hide */ - // TODO(b/315481938): Link @see VirtualDevice#getPersistentDeviceId() @SystemApi @Nullable public CharSequence getDisplayNameForPersistentDeviceId(@NonNull String persistentDeviceId) { @@ -411,9 +407,9 @@ public final class VirtualDeviceManager { * Returns all current persistent device IDs, including the ones for which no virtual device * exists, as long as one may have existed or can be created. * + * @see VirtualDevice#getPersistentDeviceId() * @hide */ - // TODO(b/315481938): Link @see VirtualDevice#getPersistentDeviceId() @SystemApi @NonNull public Set<String> getAllPersistentDeviceIds() { @@ -588,7 +584,6 @@ public final class VirtualDeviceManager { /** * Returns the persistent ID of this virtual device. */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public @Nullable String getPersistentDeviceId() { return mVirtualDeviceInternal.getPersistentDeviceId(); } @@ -1121,11 +1116,8 @@ public final class VirtualDeviceManager { * @throws SecurityException if the display is not owned by this device or is not * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED trusted} */ - @FlaggedApi(Flags.FLAG_VDM_CUSTOM_IME) public void setDisplayImePolicy(int displayId, @WindowManager.DisplayImePolicy int policy) { - if (Flags.vdmCustomIme()) { - mVirtualDeviceInternal.setDisplayImePolicy(displayId, policy); - } + mVirtualDeviceInternal.setDisplayImePolicy(displayId, policy); } /** @@ -1339,7 +1331,6 @@ public final class VirtualDeviceManager { * * @see #registerVirtualDeviceListener */ - @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) public interface VirtualDeviceListener { /** * Called whenever a new virtual device has been added to the system. diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java index 761e75bd9076..95dee9b72a88 100644 --- a/core/java/android/companion/virtual/VirtualDeviceParams.java +++ b/core/java/android/companion/virtual/VirtualDeviceParams.java @@ -440,7 +440,6 @@ public final class VirtualDeviceParams implements Parcelable { * * @see Builder#setInputMethodComponent */ - @FlaggedApi(Flags.FLAG_VDM_CUSTOM_IME) @Nullable public ComponentName getInputMethodComponent() { return mInputMethodComponent; @@ -945,7 +944,6 @@ public final class VirtualDeviceParams implements Parcelable { * @attr ref android.R.styleable#InputMethod_isVirtualDeviceOnly * @attr ref android.R.styleable#InputMethod_showInInputMethodPicker */ - @FlaggedApi(Flags.FLAG_VDM_CUSTOM_IME) @NonNull public Builder setInputMethodComponent(@Nullable ComponentName inputMethodComponent) { mInputMethodComponent = inputMethodComponent; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 885a2dbc471e..469688265ae8 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -16,7 +16,6 @@ package android.content; -import static android.app.sdksandbox.SdkSandboxManager.ACTION_START_SANDBOXED_ACTIVITY; import static android.content.ContentProvider.maybeAddUserId; import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE; import static android.security.Flags.FLAG_FRP_ENFORCEMENT; @@ -13459,28 +13458,4 @@ public class Intent implements Parcelable, Cloneable { public boolean isDocument() { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } - - /** - * @deprecated Use {@link SdkSandboxActivityAuthority#isSdkSandboxActivityIntent} instead. - * Once the other API is finalized this method will be removed. - * - * TODO(b/300059435): remove as part of the cleanup. - * - * @hide - */ - @Deprecated - @android.ravenwood.annotation.RavenwoodThrow - public boolean isSandboxActivity(@NonNull Context context) { - if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) { - return true; - } - final String sandboxPackageName = context.getPackageManager().getSdkSandboxPackageName(); - if (mPackage != null && mPackage.equals(sandboxPackageName)) { - return true; - } - if (mComponent != null && mComponent.getPackageName().equals(sandboxPackageName)) { - return true; - } - return false; - } } diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index bbfae8117b16..7cd2d31ac974 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -62,6 +62,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; /** * Provides access to an application's raw asset files; see {@link Resources} @@ -133,7 +134,7 @@ public final class AssetManager implements AutoCloseable { // Debug/reference counting implementation. @GuardedBy("this") private boolean mOpen = true; - @GuardedBy("this") private int mNumRefs = 1; + private AtomicInteger mNumRefs = new AtomicInteger(1); @GuardedBy("this") private HashMap<Long, RuntimeException> mRefStacks; private ResourcesLoader[] mLoaders; @@ -244,7 +245,7 @@ public final class AssetManager implements AutoCloseable { mObject = nativeCreate(); if (DEBUG_REFS) { - mNumRefs = 0; + mNumRefs.set(0); incRefsLocked(hashCode()); } @@ -260,7 +261,7 @@ public final class AssetManager implements AutoCloseable { private AssetManager(boolean sentinel) { mObject = nativeCreate(); if (DEBUG_REFS) { - mNumRefs = 0; + mNumRefs.set(0); incRefsLocked(hashCode()); } } @@ -324,7 +325,7 @@ public final class AssetManager implements AutoCloseable { } mOpen = false; - decRefsLocked(hashCode()); + decRefs(hashCode()); } } @@ -1235,9 +1236,7 @@ public final class AssetManager implements AutoCloseable { } void xmlBlockGone(int id) { - synchronized (this) { - decRefsLocked(id); - } + decRefs(id); } @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1308,9 +1307,7 @@ public final class AssetManager implements AutoCloseable { } void releaseTheme(long themePtr) { - synchronized (this) { - decRefsLocked(themePtr); - } + decRefs(themePtr); } static long getThemeFreeFunction() { @@ -1332,7 +1329,7 @@ public final class AssetManager implements AutoCloseable { if (this != newAssetManager) { synchronized (this) { ensureValidLocked(); - decRefsLocked(themePtr); + decRefs(themePtr); } synchronized (newAssetManager) { newAssetManager.ensureValidLocked(); @@ -1364,8 +1361,8 @@ public final class AssetManager implements AutoCloseable { @Override protected void finalize() throws Throwable { - if (DEBUG_REFS && mNumRefs != 0) { - Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs); + if (DEBUG_REFS && mNumRefs.get() != 0) { + Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs.get()); if (mRefStacks != null) { for (RuntimeException e : mRefStacks.values()) { Log.w(TAG, "Reference from here", e); @@ -1473,9 +1470,7 @@ public final class AssetManager implements AutoCloseable { nativeAssetDestroy(mAssetNativePtr); mAssetNativePtr = 0; - synchronized (AssetManager.this) { - decRefsLocked(hashCode()); - } + decRefs(hashCode()); } } @@ -1680,19 +1675,25 @@ public final class AssetManager implements AutoCloseable { RuntimeException ex = new RuntimeException(); mRefStacks.put(id, ex); } - mNumRefs++; + mNumRefs.incrementAndGet(); } - @GuardedBy("this") - private void decRefsLocked(long id) { - if (DEBUG_REFS && mRefStacks != null) { - mRefStacks.remove(id); - } - mNumRefs--; - if (mNumRefs == 0 && mObject != 0) { - nativeDestroy(mObject); - mObject = 0; - mApkAssets = sEmptyApkAssets; + private void decRefs(long id) { + if (DEBUG_REFS) { + synchronized (this) { + if (mRefStacks != null) { + mRefStacks.remove(id); + } + } + } + if (mNumRefs.decrementAndGet() == 0) { + synchronized (this) { + if (mNumRefs.get() == 0 && mObject != 0) { + nativeDestroy(mObject); + mObject = 0; + mApkAssets = sEmptyApkAssets; + } + } } } diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig index 2161e10337c9..430ed2b68342 100644 --- a/core/java/android/credentials/flags.aconfig +++ b/core/java/android/credentials/flags.aconfig @@ -144,3 +144,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + namespace: "credential_manager" + name: "fix_metric_duplication_emits" + description: "Fixes duplicate emits in the original metric emit system." + bug: "362994633" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 88d69b665c87..030c883924a7 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -182,17 +182,10 @@ public abstract class SQLiteOpenHelper implements AutoCloseable { setOpenParamsBuilder(openParamsBuilder); Object lock = null; - if (mName == null || !Flags.concurrentOpenHelper()) { + if (!Flags.concurrentOpenHelper() || mName == null) { lock = new Object(); } else { - try { - final String path = mContext.getDatabasePath(mName).getCanonicalPath(); - lock = sDbLock.computeIfAbsent(path, (String k) -> new Object()); - } catch (IOException e) { - Log.d(TAG, "failed to construct db path for " + mName); - // Ensure the lock is not null. - lock = new Object(); - } + lock = sDbLock.computeIfAbsent(mName, (String k) -> new Object()); } mLock = lock; } diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 6716598f9e4c..0590a06f3f82 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -397,7 +397,6 @@ public final class DisplayManager { * @see #createVirtualDisplay * @hide */ - @FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS) @SystemApi public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7; diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java index 4025242fd208..1a712d2b3f31 100644 --- a/core/java/android/hardware/input/KeyGestureEvent.java +++ b/core/java/android/hardware/input/KeyGestureEvent.java @@ -122,17 +122,11 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69; public static final int KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW = 70; public static final int KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW = 71; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN = 72; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT = 73; - public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 74; - public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 75; - public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 76; - public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 77; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT = 78; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT = 79; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP = 80; - public static final int KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN = 81; - public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 82; + public static final int KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION = 72; + public static final int KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK = 73; + public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 74; + public static final int KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB = 75; + public static final int KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS = 76; public static final int FLAG_CANCELLED = 1; @@ -220,16 +214,10 @@ public final class KeyGestureEvent { KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW, KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW, - KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN, - KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT, KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION, KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK, KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB, - KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT, - KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT, - KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP, - KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN, KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS, }) @Retention(RetentionPolicy.SOURCE) @@ -815,10 +803,6 @@ public final class KeyGestureEvent { return "KEY_GESTURE_TYPE_MINIMIZE_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_TOGGLE_MAXIMIZE_FREEFORM_WINDOW"; - case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN: - return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN"; - case KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT: - return "KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT"; case KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION: return "KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION"; case KEY_GESTURE_TYPE_ACTIVATE_SELECT_TO_SPEAK: @@ -827,14 +811,6 @@ public final class KeyGestureEvent { return "KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB: return "KEY_GESTURE_TYPE_TOGGLE_DO_NOT_DISTURB"; - case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT: - return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT"; - case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT: - return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT"; - case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP: - return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP"; - case KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN: - return "KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN"; case KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS: return "KEY_GESTURE_TYPE_TOGGLE_VOICE_ACCESS"; default: diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index 9181bd0cb2ed..953ee08800cf 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -771,6 +771,7 @@ public final class ContextHubManager { */ @FlaggedApi(Flags.FLAG_OFFLOAD_API) private IContextHubEndpointDiscoveryCallback createDiscoveryCallback( + IContextHubService service, Executor executor, HubEndpointDiscoveryCallback callback, @Nullable String serviceDescriptor) { @@ -779,6 +780,7 @@ public final class ContextHubManager { public void onEndpointsStarted(HubEndpointInfo[] hubEndpointInfoList) { if (hubEndpointInfoList.length == 0) { Log.w(TAG, "onEndpointsStarted: received empty discovery list"); + invokeCallbackFinished(service); return; } executor.execute( @@ -791,6 +793,7 @@ public final class ContextHubManager { } else { callback.onEndpointsStarted(discoveryList); } + invokeCallbackFinished(service); }); } @@ -798,6 +801,7 @@ public final class ContextHubManager { public void onEndpointsStopped(HubEndpointInfo[] hubEndpointInfoList, int reason) { if (hubEndpointInfoList.length == 0) { Log.w(TAG, "onEndpointsStopped: received empty discovery list"); + invokeCallbackFinished(service); return; } executor.execute( @@ -810,8 +814,17 @@ public final class ContextHubManager { } else { callback.onEndpointsStopped(discoveryList, reason); } + invokeCallbackFinished(service); }); } + + private void invokeCallbackFinished(IContextHubService service) { + try { + service.onDiscoveryCallbackFinished(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } }; } @@ -873,7 +886,7 @@ public final class ContextHubManager { Objects.requireNonNull(executor, "executor cannot be null"); Objects.requireNonNull(callback, "callback cannot be null"); IContextHubEndpointDiscoveryCallback iCallback = - createDiscoveryCallback(executor, callback, null); + createDiscoveryCallback(mService, executor, callback, null); try { mService.registerEndpointDiscoveryCallbackId(endpointId, iCallback); } catch (RemoteException e) { @@ -919,7 +932,7 @@ public final class ContextHubManager { } IContextHubEndpointDiscoveryCallback iCallback = - createDiscoveryCallback(executor, callback, serviceDescriptor); + createDiscoveryCallback(mService, executor, callback, serviceDescriptor); try { mService.registerEndpointDiscoveryCallbackDescriptor(serviceDescriptor, iCallback); } catch (RemoteException e) { diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl index d5b3fa251e82..bb5491d98cf9 100644 --- a/core/java/android/hardware/location/IContextHubService.aidl +++ b/core/java/android/hardware/location/IContextHubService.aidl @@ -150,4 +150,8 @@ interface IContextHubService { // Unregister an endpoint with the context hub @EnforcePermission("ACCESS_CONTEXT_HUB") void unregisterEndpointDiscoveryCallback(in IContextHubEndpointDiscoveryCallback callback); + + // Called when a discovery callback is finished executing + @EnforcePermission("ACCESS_CONTEXT_HUB") + void onDiscoveryCallbackFinished(); } diff --git a/core/java/android/os/AppZygote.java b/core/java/android/os/AppZygote.java index 0541a96e990e..69b6597d717a 100644 --- a/core/java/android/os/AppZygote.java +++ b/core/java/android/os/AppZygote.java @@ -16,15 +16,22 @@ package android.os; +import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; + +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.Zygote; import dalvik.system.VMRuntime; +import java.util.Map; + /** * AppZygote is responsible for interfacing with an application-specific zygote. * @@ -94,12 +101,90 @@ public class AppZygote { return mAppInfo; } + /** + * Start a new process. + * + * <p>Wrap ZygoteProcess.start with retry logic. + * + * @param processClass The class to use as the process's main entry + * point. + * @param niceName A more readable name to use for the process. + * @param uid The user-id under which the process will run. + * @param gids Additional group-ids associated with the process. + * @param runtimeFlags Additional flags. + * @param targetSdkVersion The target SDK version for the app. + * @param seInfo null-ok SELinux information for the new process. + * @param abi non-null the ABI this app should be started with. + * @param instructionSet null-ok the instruction set to use. + * @param appDataDir null-ok the data directory of the app. + * @param packageName null-ok the name of the package this process belongs to. + * @param isTopApp Whether the process starts for high priority application. + * @param disabledCompatChanges null-ok list of disabled compat changes for the process being + * started. + * @param pkgDataInfoMap Map from related package names to private data directory + * volume UUID and inode number. + * @param allowlistedDataInfoList Map from allowlisted package names to private data directory + * volume UUID and inode number. + * @param zygoteArgs Additional arguments to supply to the Zygote process. + * @return An object that describes the result of the attempt to start the process. + * @throws RuntimeException on fatal start failure + */ + public final Process.ProcessStartResult startProcess(@NonNull final String processClass, + final String niceName, + int uid, @Nullable int[] gids, + int runtimeFlags, int mountExternal, + int targetSdkVersion, + @Nullable String seInfo, + @NonNull String abi, + @Nullable String instructionSet, + @Nullable String appDataDir, + @Nullable String packageName, + boolean isTopApp, + @Nullable long[] disabledCompatChanges, + @Nullable Map<String, Pair<String, Long>> + pkgDataInfoMap, + @Nullable Map<String, Pair<String, Long>> + allowlistedDataInfoList, + @Nullable String[] zygoteArgs) { + try { + return getProcess().start(processClass, + niceName, uid, uid, gids, runtimeFlags, mountExternal, + targetSdkVersion, seInfo, abi, instructionSet, + appDataDir, null, packageName, + /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, + disabledCompatChanges, pkgDataInfoMap, allowlistedDataInfoList, + false, false, false, + zygoteArgs); + } catch (RuntimeException e) { + if (!Flags.appZygoteRetryStart()) { + throw e; + } + final boolean zygote_dead = getProcess().isDead(); + if (!zygote_dead) { + throw e; // Zygote process is alive. Do nothing. + } + } + // Retry here if the previous start fails. + Log.w(LOG_TAG, "retry starting process " + niceName); + stopZygote(); + return getProcess().start(processClass, + niceName, uid, uid, gids, runtimeFlags, mountExternal, + targetSdkVersion, seInfo, abi, instructionSet, + appDataDir, null, packageName, + /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, + disabledCompatChanges, pkgDataInfoMap, allowlistedDataInfoList, + false, false, false, + zygoteArgs); + } + @GuardedBy("mLock") private void stopZygoteLocked() { if (mZygote != null) { mZygote.close(); // use killProcessGroup() here, so we kill all untracked children as well. - Process.killProcessGroup(mZygoteUid, mZygote.getPid()); + if (!mZygote.isDead()) { + Process.killProcessGroup(mZygoteUid, mZygote.getPid()); + } mZygote = null; } } diff --git a/core/java/android/os/ChildZygoteProcess.java b/core/java/android/os/ChildZygoteProcess.java index 337a3e279a1a..d8f825a2ee60 100644 --- a/core/java/android/os/ChildZygoteProcess.java +++ b/core/java/android/os/ChildZygoteProcess.java @@ -17,6 +17,10 @@ package android.os; import android.net.LocalSocketAddress; +import android.system.ErrnoException; +import android.system.Os; + +import java.util.concurrent.atomic.AtomicBoolean; /** * Represents a connection to a child-zygote process. A child-zygote is spawend from another @@ -30,9 +34,23 @@ public class ChildZygoteProcess extends ZygoteProcess { */ private final int mPid; - ChildZygoteProcess(LocalSocketAddress socketAddress, int pid) { + /** + * The UID of the child zygote process. + */ + private final int mUid; + + + /** + * If this zygote process was dead; + */ + private AtomicBoolean mDead; + + + ChildZygoteProcess(LocalSocketAddress socketAddress, int pid, int uid) { super(socketAddress, null); mPid = pid; + mUid = uid; + mDead = new AtomicBoolean(false); } /** @@ -41,4 +59,22 @@ public class ChildZygoteProcess extends ZygoteProcess { public int getPid() { return mPid; } + + /** + * Check if child-zygote process is dead + */ + public boolean isDead() { + if (mDead.get()) { + return true; + } + try { + if (Os.stat("/proc/" + mPid).st_uid == mUid) { + return false; + } + } catch (ErrnoException e) { + // Do nothing, it's dead. + } + mDead.set(true); + return true; + } } diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index 9435f4d59a2c..77b6d70339ab 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -351,4 +351,10 @@ public abstract class PowerManagerInternal { * return false if ambient display is not available. */ public abstract boolean isAmbientDisplaySuppressed(); + + /** + * Notifies PowerManager that the device has entered a postured state (stationary + upright). + * This may affect dream eligibility. + */ + public abstract void setDevicePostured(boolean isPostured); } diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING index effe5554aff4..48fa0c8277df 100644 --- a/core/java/android/os/TEST_MAPPING +++ b/core/java/android/os/TEST_MAPPING @@ -112,6 +112,32 @@ { "file_patterns": ["Bugreport[^/]*\\.java"], "name": "ShellTests" + }, + { + "file_patterns": [ + "CpuHeadroom[^/]*", + "GpuHeadroom[^/]*", + "health/SystemHealthManager\\.java" + ], + "name": "CtsOsTestCases", + "options": [ + {"include-filter": "android.os.health.cts.HeadroomTest"}, + {"exclude-annotation": "androidx.test.filters.FlakyTest"}, + {"exclude-annotation": "org.junit.Ignore"} + ] + }, + { + "file_patterns": [ + "CpuHeadroom[^/]*", + "GpuHeadroom[^/]*", + "health/SystemHealthManager\\.java" + ], + "name": "FrameworksCoreTests", + "options": [ + {"include-filter": "android.os.SystemHealthManagerUnitTest"}, + {"exclude-annotation": "androidx.test.filters.FlakyTest"}, + {"exclude-annotation": "org.junit.Ignore"} + ] } ], "ravenwood-presubmit": [ diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 73a74b2f8abc..2d487b1e77d5 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -1319,6 +1319,6 @@ public class ZygoteProcess { throw new RuntimeException("Starting child-zygote through Zygote failed", ex); } - return new ChildZygoteProcess(serverAddress, result.pid); + return new ChildZygoteProcess(serverAddress, result.pid, uid); } } diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig index 8b8369890d1b..b12433a73a31 100644 --- a/core/java/android/os/flags.aconfig +++ b/core/java/android/os/flags.aconfig @@ -150,6 +150,13 @@ flag { } flag { + name: "app_zygote_retry_start" + namespace: "arc_next" + description: "Guard the new added retry logic in app zygote." + bug: "361799815" +} + +flag { name: "battery_part_status_api" is_exported: true namespace: "phoenix" diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 343d7527ea98..518820430419 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -2045,7 +2045,7 @@ public final class PermissionManager { if (deviceId == Context.DEVICE_ID_DEFAULT) { persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT; - } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) { + } else { VirtualDeviceManager virtualDeviceManager = mContext.getSystemService( VirtualDeviceManager.class); if (virtualDeviceManager != null) { @@ -2059,9 +2059,6 @@ public final class PermissionManager { Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId); } } - } else { - Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId - + "is not default."); } return persistentDeviceId; } diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl index 1c0a2c021bca..3ca9d937b0ca 100644 --- a/core/java/android/service/dreams/IDreamManager.aidl +++ b/core/java/android/service/dreams/IDreamManager.aidl @@ -53,6 +53,8 @@ interface IDreamManager { void startDreamActivity(in Intent intent); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)") oneway void setDreamIsObscured(in boolean isObscured); + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)") + oneway void setDevicePostured(in boolean isPostured); oneway void startDozingOneway(in IBinder token, int screenState, int reason, float screenBrightnessFloat, int screenBrightnessInt, boolean useNormalBrightnessForDoze); diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 990b099d616e..464756842caf 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -325,6 +325,7 @@ public abstract class WallpaperService extends Service { IWindowSession mSession; final Object mLock = new Object(); + private final Object mSurfaceReleaseLock = new Object(); boolean mOffsetMessageEnqueued; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -1075,9 +1076,11 @@ public abstract class WallpaperService extends Service { animator.setDuration(DIMMING_ANIMATION_DURATION_MS); animator.addUpdateListener((ValueAnimator va) -> { final float dimValue = (float) va.getAnimatedValue(); - if (mBbqSurfaceControl != null) { - surfaceControlTransaction - .setAlpha(mBbqSurfaceControl, 1 - dimValue).apply(); + synchronized (mSurfaceReleaseLock) { + if (mBbqSurfaceControl != null && mBbqSurfaceControl.isValid()) { + surfaceControlTransaction + .setAlpha(mBbqSurfaceControl, 1 - dimValue).apply(); + } } }); animator.addListener(new AnimatorListenerAdapter() { @@ -2356,35 +2359,39 @@ public abstract class WallpaperService extends Service { if (DEBUG) Log.v(TAG, "onDestroy(): " + this); onDestroy(); - if (mCreated) { - try { - if (DEBUG) Log.v(TAG, "Removing window and destroying surface " - + mSurfaceHolder.getSurface() + " of: " + this); + synchronized (mSurfaceReleaseLock) { + if (mCreated) { + try { + if (DEBUG) { + Log.v(TAG, "Removing window and destroying surface " + + mSurfaceHolder.getSurface() + " of: " + this); + } - if (mInputEventReceiver != null) { - mInputEventReceiver.dispose(); - mInputEventReceiver = null; - } + if (mInputEventReceiver != null) { + mInputEventReceiver.dispose(); + mInputEventReceiver = null; + } - mSession.remove(mWindow.asBinder()); - } catch (RemoteException e) { - } - mSurfaceHolder.mSurface.release(); - if (mBlastBufferQueue != null) { - mBlastBufferQueue.destroy(); - mBlastBufferQueue = null; - } - if (mBbqSurfaceControl != null) { - new SurfaceControl.Transaction().remove(mBbqSurfaceControl).apply(); - mBbqSurfaceControl = null; + mSession.remove(mWindow.asBinder()); + } catch (RemoteException e) { + } + mSurfaceHolder.mSurface.release(); + if (mBlastBufferQueue != null) { + mBlastBufferQueue.destroy(); + mBlastBufferQueue = null; + } + if (mBbqSurfaceControl != null) { + new SurfaceControl.Transaction().remove(mBbqSurfaceControl).apply(); + mBbqSurfaceControl = null; + } + mCreated = false; } - mCreated = false; - } - if (mSurfaceControl != null) { - mSurfaceControl.release(); - mSurfaceControl = null; - mRelayoutResult = null; + if (mSurfaceControl != null) { + mSurfaceControl.release(); + mSurfaceControl = null; + mRelayoutResult = null; + } } } @@ -2417,9 +2424,10 @@ public abstract class WallpaperService extends Service { Surface ret = null; if (mBlastBufferQueue == null) { - mBlastBufferQueue = new BLASTBufferQueue("Wallpaper", mBbqSurfaceControl, - width, height, format); + mBlastBufferQueue = new BLASTBufferQueue("Wallpaper", + true /* updateDestinationFrame */); mBlastBufferQueue.setApplyToken(mBbqApplyToken); + mBlastBufferQueue.update(mBbqSurfaceControl, width, height, format); // We only return the Surface the first time, as otherwise // it hasn't changed and there is no need to update. ret = mBlastBufferQueue.createSurface(); diff --git a/core/java/android/timezone/TelephonyNetworkFinder.java b/core/java/android/timezone/TelephonyNetworkFinder.java index c69ddf86d3f8..fb4a19b9dcac 100644 --- a/core/java/android/timezone/TelephonyNetworkFinder.java +++ b/core/java/android/timezone/TelephonyNetworkFinder.java @@ -19,6 +19,9 @@ package android.timezone; import android.annotation.NonNull; import android.annotation.Nullable; +import com.android.i18n.timezone.MobileCountries; +import com.android.icu.Flags; + import java.util.Objects; /** @@ -50,4 +53,17 @@ public final class TelephonyNetworkFinder { return telephonyNetworkDelegate != null ? new TelephonyNetwork(telephonyNetworkDelegate) : null; } + + /** + * Returns the countries where a given MCC is in use. + */ + @Nullable + public MobileCountries findCountriesByMcc(@NonNull String mcc) { + Objects.requireNonNull(mcc); + + if (!Flags.telephonyLookupMccExtension()) { + return null; + } + return mDelegate.findCountriesByMcc(mcc); + } } diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 028043340732..06eb0428bfcf 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -227,9 +227,6 @@ interface IWindowManager @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void endProlongedAnimations(); - void startFreezingScreen(int exitAnim, int enterAnim); - void stopFreezingScreen(); - // these require DISABLE_KEYGUARD permission /** @deprecated use Activity.setShowWhenLocked instead. */ void disableKeyguard(IBinder token, String tag, int userId); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index d7cf3e827695..311fbee2fc4b 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -3026,6 +3026,7 @@ public final class SurfaceControl implements Parcelable { // Only non-null if the SurfaceControlRegistry is enabled. This list tracks the set of calls // made through this transaction object, and is dumped (and cleared) when the transaction is // later applied. + @Nullable ArrayList<String> mCalls; Runnable mFreeNativeResources; @@ -4898,8 +4899,10 @@ public final class SurfaceControl implements Parcelable { SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( "merge", this, null, "otherTx=" + other.getId()); if (mCalls != null) { - mCalls.addAll(other.mCalls); - other.mCalls.clear(); + if (other.mCalls != null) { + mCalls.addAll(other.mCalls); + other.mCalls.clear(); + } } } mResizedSurfaces.putAll(other.mResizedSurfaces); diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java index 121c01be7294..0b528bffe5c5 100644 --- a/core/java/android/view/SurfaceControlRegistry.java +++ b/core/java/android/view/SurfaceControlRegistry.java @@ -334,13 +334,17 @@ public class SurfaceControlRegistry { if (call == APPLY) { // Log the apply and dump the calls on that transaction Log.e(TAG, msg, new Throwable()); - for (int i = 0; i < tx.mCalls.size(); i++) { - Log.d(TAG, " " + tx.mCalls.get(i)); + if (tx.mCalls != null) { + for (int i = 0; i < tx.mCalls.size(); i++) { + Log.d(TAG, " " + tx.mCalls.get(i)); + } } } else if (matchesForCallStackDebugging(sc != null ? sc.getName() : null, call)) { // Otherwise log this call to the transaction if it matches the tracked calls Log.e(TAG, msg, new Throwable()); - tx.mCalls.add(msg); + if (tx.mCalls != null) { + tx.mCalls.add(msg); + } } } else { // Log this call if it matches the tracked calls diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 36671b901a6b..64e7becb1ed4 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -134,7 +134,6 @@ import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme; import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay; import static com.android.window.flags.Flags.predictiveBackSwipeEdgeNoneApi; import static com.android.window.flags.Flags.setScPropertiesInClient; -import static com.android.window.flags.Flags.systemUiImmersiveConfirmationDialog; import android.Manifest; import android.accessibilityservice.AccessibilityService; @@ -377,16 +376,6 @@ public final class ViewRootImpl implements ViewParent, SystemProperties.getBoolean("persist.wm.debug.client_transient", false); /** - * Whether the client (system UI) is handling the immersive confirmation window. If - * {@link CLIENT_TRANSIENT} is set to true, the immersive confirmation window will always be the - * client instance and this flag will be ignored. Otherwise, the immersive confirmation window - * can be switched freely by this flag. - * @hide - */ - public static final boolean CLIENT_IMMERSIVE_CONFIRMATION = - systemUiImmersiveConfirmationDialog(); - - /** * Set this system property to true to force the view hierarchy to render * at 60 Hz. This can be used to measure the potential framerate. */ @@ -2770,14 +2759,15 @@ public final class ViewRootImpl implements ViewParent, if (mBlastBufferQueue != null) { mBlastBufferQueue.destroy(); } - mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, - mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format); - mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback); - mBlastBufferQueue.setWaitForBufferReleaseCallback(mChoreographer::onWaitForBufferRelease); + mBlastBufferQueue = new BLASTBufferQueue(mTag, true /* updateDestinationFrame */); // If we create and destroy BBQ without recreating the SurfaceControl, we can end up // queuing buffers on multiple apply tokens causing out of order buffer submissions. We // fix this by setting the same apply token on all BBQs created by this VRI. mBlastBufferQueue.setApplyToken(mBbqApplyToken); + mBlastBufferQueue.update(mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y, + mWindowAttributes.format); + mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback); + mBlastBufferQueue.setWaitForBufferReleaseCallback(mChoreographer::onWaitForBufferRelease); Surface blastSurface; if (addSchandleToVriSurface()) { blastSurface = mBlastBufferQueue.createSurfaceWithHandle(); @@ -5562,6 +5552,9 @@ public final class ViewRootImpl implements ViewParent, if (mAttachInfo.mContentCaptureManager != null) { ContentCaptureSession session = mAttachInfo.mContentCaptureManager.getMainContentCaptureSession(); + if (android.view.contentcapture.flags.Flags.postCreateAndroidBgThread()) { + session.performStart(); + } session.notifyWindowBoundsChanged(session.getId(), getConfiguration().windowConfiguration.getBounds()); } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 25bd713d9191..a5da0c3ce5b1 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -50,6 +50,7 @@ import android.window.TrustedPresentationThresholds; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; +import com.android.internal.policy.PhoneWindow; import com.android.internal.util.FastPrintWriter; import java.io.FileDescriptor; @@ -375,7 +376,8 @@ public final class WindowManagerGlobal { if (context != null && wparams.type > LAST_APPLICATION_WINDOW) { final TypedArray styles = context.obtainStyledAttributes(R.styleable.Window); - if (styles.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false)) { + if (PhoneWindow.isOptingOutEdgeToEdgeEnforcement( + context.getApplicationInfo(), true /* local */, styles)) { wparams.privateFlags |= PRIVATE_FLAG_OPT_OUT_EDGE_TO_EDGE; } styles.recycle(); diff --git a/core/java/android/view/contentcapture/ChildContentCaptureSession.java b/core/java/android/view/contentcapture/ChildContentCaptureSession.java index 8baa55f8e377..6e2e1009fd40 100644 --- a/core/java/android/view/contentcapture/ChildContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ChildContentCaptureSession.java @@ -74,8 +74,8 @@ final class ChildContentCaptureSession extends ContentCaptureSession { } @Override - void flush(@FlushReason int reason) { - mParent.flush(reason); + void internalFlush(@FlushReason int reason) { + mParent.internalFlush(reason); } @Override diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 724e8fa830af..b7a77d701045 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -52,7 +52,6 @@ import android.view.contentcapture.ContentCaptureSession.FlushReason; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.RingBuffer; import com.android.internal.util.SyncResultReceiver; @@ -605,7 +604,6 @@ public final class ContentCaptureManager { mContext, this, prepareUiHandler(), - prepareContentCaptureHandler(), mService ); if (sVerbose) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession); @@ -616,15 +614,6 @@ public final class ContentCaptureManager { @NonNull @GuardedBy("mLock") - private Handler prepareContentCaptureHandler() { - if (mContentCaptureHandler == null) { - mContentCaptureHandler = BackgroundThread.getHandler(); - } - return mContentCaptureHandler; - } - - @NonNull - @GuardedBy("mLock") private Handler prepareUiHandler() { if (mUiHandler == null) { mUiHandler = Handler.createAsync(Looper.getMainLooper()); @@ -674,7 +663,7 @@ public final class ContentCaptureManager { @UiThread public void flush(@FlushReason int reason) { if (mOptions.lite) return; - getMainContentCaptureSession().flush(reason); + getMainContentCaptureSession().internalFlush(reason); } /** diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 9aeec20ec9b7..791a6f4254ec 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -286,6 +286,9 @@ public abstract class ContentCaptureSession implements AutoCloseable { abstract void start(@NonNull IBinder token, @NonNull IBinder shareableActivityToken, @NonNull ComponentName component, int flags); + /** @hide */ + public void performStart() {} + abstract boolean isDisabled(); /** @@ -339,7 +342,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { /** * Flushes the buffered events to the service. */ - abstract void flush(@FlushReason int reason); + abstract void internalFlush(@FlushReason int reason); /** * Sets the {@link ContentCaptureContext} associated with the session. diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 2fb78c038ca2..29cae857098d 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -57,10 +57,12 @@ import android.view.View; import android.view.ViewStructure; import android.view.autofill.AutofillId; import android.view.contentcapture.ViewNode.ViewStructureImpl; +import android.view.contentcapture.flags.Flags; import android.view.contentprotection.ContentProtectionEventProcessor; import android.view.inputmethod.BaseInputConnection; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; import com.android.internal.os.IResultReceiver; import com.android.modules.expresslog.Counter; @@ -107,8 +109,10 @@ public final class MainContentCaptureSession extends ContentCaptureSession { @NonNull private final Handler mUiHandler; - @NonNull - private final Handler mContentCaptureHandler; + /** @hide */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + @Nullable + public Handler mContentCaptureHandler; /** * Interface to the system_server binder object - it's only used to start the session (and @@ -187,6 +191,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { @Nullable public ContentProtectionEventProcessor mContentProtectionEventProcessor; + /** + * A runnable object to perform the start of this session. + */ + @Nullable + private Runnable mStartRunnable = null; + private static class SessionStateReceiver extends IResultReceiver.Stub { private final WeakReference<MainContentCaptureSession> mMainSession; @@ -198,7 +208,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { public void send(int resultCode, Bundle resultData) { final MainContentCaptureSession mainSession = mMainSession.get(); if (mainSession == null) { - Log.w(TAG, "received result after mina session released"); + Log.w(TAG, "received result after main session released"); return; } final IBinder binder; @@ -213,6 +223,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { binder = resultData.getBinder(EXTRA_BINDER); if (binder == null) { Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result"); + // explicitly init the bg thread + mainSession.mContentCaptureHandler = mainSession.prepareContentCaptureHandler(); mainSession.runOnContentCaptureThread(() -> mainSession.resetSession( STATE_DISABLED | STATE_INTERNAL_ERROR)); return; @@ -220,23 +232,45 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } else { binder = null; } + // explicitly init the bg thread + mainSession.mContentCaptureHandler = mainSession.prepareContentCaptureHandler(); mainSession.runOnContentCaptureThread(() -> mainSession.onSessionStarted(resultCode, binder)); } } + /** + * Prepares the content capture handler(i.e. the background thread). + * + * This is expected to be called from the {@link SessionStateReceiver#send} callback, after the + * session {@link performStart}. This is expected to be executed in a binder thread, instead + * of the UI thread. + */ + @NonNull + private Handler prepareContentCaptureHandler() { + if (mContentCaptureHandler == null) { + try { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareContentCaptureHandler"); + } + mContentCaptureHandler = BackgroundThread.getHandler(); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + } + return mContentCaptureHandler; + } + /** @hide */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) public MainContentCaptureSession( @NonNull ContentCaptureManager.StrippedContext context, @NonNull ContentCaptureManager manager, @NonNull Handler uiHandler, - @NonNull Handler contentCaptureHandler, @NonNull IContentCaptureManager systemServerInterface) { mContext = context; mManager = manager; mUiHandler = uiHandler; - mContentCaptureHandler = contentCaptureHandler; mSystemServerInterface = systemServerInterface; final int logHistorySize = mManager.mOptions.logHistorySize; @@ -260,18 +294,49 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } /** - * Starts this session. + * Performs the start of the session. + * + * This is expected to be called from the UI thread, when the activity finishes its first frame. + * This is a no-op if the session has already been started. + * + * See {@link #start(IBinder, IBinder, ComponentName, int)} for more details. + * + * @hide */ + @Override + public void performStart() { + if (!hasStarted() && mStartRunnable != null) { + mStartRunnable.run(); + } + } + + /** + * Creates a runnable to start this session. + * + * For performance reasons, it is better to only create a task to start the session + * during the creation of the activity and perform the actual start when the activity + * finishes it's first frame. */ @Override void start(@NonNull IBinder token, @NonNull IBinder shareableActivityToken, @NonNull ComponentName component, int flags) { - runOnContentCaptureThread( - () -> startImpl(token, shareableActivityToken, component, flags)); + if (Flags.postCreateAndroidBgThread()) { + mStartRunnable = () -> { + try { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "cc session startImpl"); + } + startImpl(token, shareableActivityToken, component, flags); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + }; + } else { + startImpl(token, shareableActivityToken, component, flags); + } } private void startImpl(@NonNull IBinder token, @NonNull IBinder shareableActivityToken, @NonNull ComponentName component, int flags) { - checkOnContentCaptureThread(); if (!isContentCaptureEnabled()) return; if (sVerbose) { @@ -305,11 +370,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { Log.w(TAG, "Error starting session for " + component.flattenToShortString() + ": " + e); } } + @Override void onDestroy() { clearAndRunOnContentCaptureThread(() -> { try { - flush(FLUSH_REASON_SESSION_FINISHED); + internalFlush(FLUSH_REASON_SESSION_FINISHED); } finally { destroySession(); } @@ -557,11 +623,10 @@ public final class MainContentCaptureSession extends ContentCaptureSession { flushReason = forceFlush ? FLUSH_REASON_FORCE_FLUSH : FLUSH_REASON_FULL; } - flush(flushReason); + internalFlush(flushReason); } private boolean hasStarted() { - checkOnContentCaptureThread(); return mState != UNKNOWN_STATE; } @@ -575,6 +640,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { if (sVerbose) Log.v(TAG, "handleScheduleFlush(): session not started yet"); return; } + if (mContentCaptureHandler == null) { + Log.w(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): content capture " + + "thread not ready"); + return; + } if (mDisabled.get()) { // Should not be called on this state, as handleSendEvent checks. @@ -617,15 +687,18 @@ public final class MainContentCaptureSession extends ContentCaptureSession { if (sVerbose) Log.v(TAG, "Nothing to flush"); return; } - flush(reason); + internalFlush(reason); } - /** @hide */ + /** + * Internal API to flush the buffered events to the service. + * + * Do not confuse this with the public API {@link #flush()}. + * + * @hide */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @Override - public void flush(@FlushReason int reason) { - // TODO: b/380381249 renaming the internal APIs to prevent confusions between this and the - // public API. + public void internalFlush(@FlushReason int reason) { runOnContentCaptureThread(() -> flushImpl(reason)); } @@ -647,6 +720,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { if (!isContentCaptureReceiverEnabled()) { return; } + if (mContentCaptureHandler == null) { + Log.w(TAG, "handleForceFlush(" + getDebugState(reason) + "): content capture thread" + + "not ready"); + return; + } if (mDirectServiceInterface == null) { if (sVerbose) { @@ -763,7 +841,9 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } mDirectServiceInterface = null; mContentProtectionEventProcessor = null; - mContentCaptureHandler.removeMessages(MSG_FLUSH); + if (mContentCaptureHandler != null) { + mContentCaptureHandler.removeMessages(MSG_FLUSH); + } } @Override @@ -917,6 +997,10 @@ public final class MainContentCaptureSession extends ContentCaptureSession { * clear the buffer events then starting sending out current event. */ private void enqueueEvent(@NonNull final ContentCaptureEvent event, boolean forceFlush) { + if (mContentCaptureHandler == null) { + mEventProcessQueue.offer(event); + return; + } if (forceFlush || mEventProcessQueue.size() >= mManager.mOptions.maxBufferSize - 1) { // The buffer events are cleared in the same thread first to prevent new events // being added during the time of context switch. This would disrupt the sequence @@ -1119,6 +1203,10 @@ public final class MainContentCaptureSession extends ContentCaptureSession { * always delegate to the assigned thread from {@code mHandler} for synchronization.</p> */ private void checkOnContentCaptureThread() { + if (mContentCaptureHandler == null) { + Log.e(TAG, "content capture thread is not initiallized!"); + return; + } final boolean onContentCaptureThread = mContentCaptureHandler.getLooper().isCurrentThread(); if (!onContentCaptureThread) { mWrongThreadCount.incrementAndGet(); @@ -1139,6 +1227,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { * </p> */ private void runOnContentCaptureThread(@NonNull Runnable r) { + if (mContentCaptureHandler == null) { + Log.e(TAG, "content capture thread is not initiallized!"); + // fall back to UI thread + runOnUiThread(r); + return; + } if (!mContentCaptureHandler.getLooper().isCurrentThread()) { mContentCaptureHandler.post(r); } else { @@ -1147,6 +1241,12 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } private void clearAndRunOnContentCaptureThread(@NonNull Runnable r, int what) { + if (mContentCaptureHandler == null) { + Log.e(TAG, "content capture thread is not initiallized!"); + // fall back to UI thread + runOnUiThread(r); + return; + } if (!mContentCaptureHandler.getLooper().isCurrentThread()) { mContentCaptureHandler.removeMessages(what); mContentCaptureHandler.post(r); diff --git a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig index f709ed7f57cd..9df835098268 100644 --- a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig +++ b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig @@ -13,4 +13,16 @@ flag { namespace: "machine_learning" description: "Feature flag for baklava content capture API" bug: "380381249" + is_exported: true +} + +flag { + name: "post_create_android_bg_thread" + namespace: "pixel_state_server" + description: "Feature flag to post create the bg thread when an app is in the allowlist" + bug: "376468525" + is_fixed_read_only: true + metadata { + purpose: PURPOSE_BUGFIX + } } diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java index 0a83bdc35b1f..8fef2d726b2c 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -766,7 +766,6 @@ public final class InputMethodInfo implements Parcelable { * Returns true if IME supports only virtual devices. * @hide */ - @FlaggedApi(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_IME) @SystemApi public boolean isVirtualDeviceOnly() { return mIsVirtualDeviceOnly; diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java index 33890b80869d..f70bf9737636 100644 --- a/core/java/android/widget/Magnifier.java +++ b/core/java/android/widget/Magnifier.java @@ -1021,8 +1021,9 @@ public final class Magnifier { .setCallsite("InternalPopupWindow") .build(); - mBBQ = new BLASTBufferQueue("magnifier surface", mBbqSurfaceControl, - surfaceWidth, surfaceHeight, PixelFormat.TRANSLUCENT); + mBBQ = new BLASTBufferQueue("magnifier surface", /*updateDestinationFrame*/ true); + mBBQ.update(mBbqSurfaceControl, + surfaceWidth, surfaceHeight, PixelFormat.TRANSLUCENT); mSurface = mBBQ.createSurface(); // Setup the RenderNode tree. The root has two children, one containing the bitmap diff --git a/core/java/android/window/TaskFragmentOperation.java b/core/java/android/window/TaskFragmentOperation.java index 6f7660a0fb3d..9d0ea547e734 100644 --- a/core/java/android/window/TaskFragmentOperation.java +++ b/core/java/android/window/TaskFragmentOperation.java @@ -161,6 +161,16 @@ public final class TaskFragmentOperation implements Parcelable { */ public static final int OP_TYPE_SET_PINNED = 19; + /** + * Sets whether this TaskFragment can affect system UI flags such as the status bar. Default + * is {@code true}. + * + * This operation is only allowed for system organizers. See + * {@link com.android.server.wm.TaskFragmentOrganizerController#registerOrganizer( + * ITaskFragmentOrganizer, boolean)} + */ + public static final int OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS = 20; + @IntDef(prefix = { "OP_TYPE_" }, value = { OP_TYPE_UNKNOWN, OP_TYPE_CREATE_TASK_FRAGMENT, @@ -183,6 +193,7 @@ public final class TaskFragmentOperation implements Parcelable { OP_TYPE_SET_MOVE_TO_BOTTOM_IF_CLEAR_WHEN_LAUNCH, OP_TYPE_SET_DECOR_SURFACE_BOOSTED, OP_TYPE_SET_PINNED, + OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS, }) @Retention(RetentionPolicy.SOURCE) public @interface OperationType {} diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java index 2c21417fb790..ddbf9e49bb8d 100644 --- a/core/java/android/window/TransitionInfo.java +++ b/core/java/android/window/TransitionInfo.java @@ -211,7 +211,7 @@ public final class TransitionInfo implements Parcelable { FLAG_CONFIG_AT_END, FLAG_IS_TASK_DISPLAY_AREA, FLAG_FIRST_CUSTOM - }, flag = true) + }) public @interface ChangeFlags {} private final @TransitionType int mType; diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig index 409c3cd569ab..c2e305d72dd0 100644 --- a/core/java/android/window/flags/windowing_frontend.aconfig +++ b/core/java/android/window/flags/windowing_frontend.aconfig @@ -257,14 +257,6 @@ flag { } flag { - name: "system_ui_immersive_confirmation_dialog" - namespace: "windowing_frontend" - description: "Enable the implementation of the immersive confirmation dialog on system UI side by default" - bug: "359713629" - is_fixed_read_only: true -} - -flag { name: "ensure_wallpaper_in_transitions" namespace: "windowing_frontend" description: "Ensure that wallpaper window tokens are always present/available for collection in transitions" @@ -426,6 +418,17 @@ flag { } flag { + name: "use_rt_frame_callback_for_splash_screen_transfer" + namespace: "windowing_frontend" + description: "report SplashscreenView shown after RtFrame commit" + is_fixed_read_only: true + bug: "387231234" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "port_window_size_animation" namespace: "windowing_frontend" description: "Port window-resize animation from legacy to shell" @@ -433,6 +436,13 @@ flag { } flag { + name: "aod_transition" + namespace: "windowing_frontend" + description: "Support to show lock wallpaper in aod state" + bug: "361438779" +} + +flag { name: "check_disabled_snapshots_in_task_persister" namespace: "windowing_frontend" description: "Check for TaskSnapshots disabling in TaskSnapshotPersister." @@ -440,4 +450,4 @@ flag { metadata { purpose: PURPOSE_BUGFIX } -} +}
\ No newline at end of file diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 644d69919998..9d7bedc4d0c3 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -689,14 +689,15 @@ public class IntentForwarderActivity extends Activity { } private void setMiniresolverPadding() { - Insets systemWindowInsets = - getWindowManager().getCurrentWindowMetrics().getWindowInsets().getInsets( - WindowInsets.Type.systemBars()); - View buttonContainer = findViewById(R.id.button_bar_container); - buttonContainer.setPadding(0, 0, 0, - systemWindowInsets.bottom + getResources().getDimensionPixelOffset( - R.dimen.resolver_button_bar_spacing)); + if (buttonContainer != null) { + Insets systemWindowInsets = + getWindowManager().getCurrentWindowMetrics().getWindowInsets().getInsets( + WindowInsets.Type.systemBars()); + buttonContainer.setPadding(0, 0, 0, + systemWindowInsets.bottom + getResources().getDimensionPixelOffset( + R.dimen.resolver_button_bar_spacing)); + } } @VisibleForTesting diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index a1945352ae09..db65d31f59da 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -929,8 +929,11 @@ public class ResolverActivity extends Activity implements if (shouldUseMiniResolver()) { View buttonContainer = findViewById(R.id.button_bar_container); - buttonContainer.setPadding(0, 0, 0, mSystemWindowInsets.bottom - + getResources().getDimensionPixelOffset(R.dimen.resolver_button_bar_spacing)); + if (buttonContainer != null) { + buttonContainer.setPadding(0, 0, 0, mSystemWindowInsets.bottom + + getResources().getDimensionPixelOffset( + R.dimen.resolver_button_bar_spacing)); + } } // Need extra padding so the list can fully scroll up diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index 6ad7fef95357..e170d6652863 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -172,8 +172,7 @@ public class NativeLibraryHelper { private static native long nativeOpenApkFd(FileDescriptor fd, String debugPath); private static native void nativeClose(long handle); - private static native long nativeSumNativeBinaries(long handle, String cpuAbi, - boolean debuggable); + private static native long nativeSumNativeBinaries(long handle, String cpuAbi); private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath, String abiToCopy, boolean extractNativeLibs, boolean debuggable); @@ -188,7 +187,7 @@ public class NativeLibraryHelper { private static long sumNativeBinaries(Handle handle, String abi) { long sum = 0; for (long apkHandle : handle.apkHandles) { - sum += nativeSumNativeBinaries(apkHandle, abi, handle.debuggable); + sum += nativeSumNativeBinaries(apkHandle, abi); } return sum; } @@ -222,7 +221,7 @@ public class NativeLibraryHelper { public static int findSupportedAbi(Handle handle, String[] supportedAbis) { int finalRes = NO_NATIVE_LIBRARIES; for (long apkHandle : handle.apkHandles) { - final int res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable); + final int res = nativeFindSupportedAbi(apkHandle, supportedAbis); if (res == NO_NATIVE_LIBRARIES) { // No native code, keep looking through all APKs. } else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) { @@ -244,8 +243,7 @@ public class NativeLibraryHelper { return finalRes; } - private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis, - boolean debuggable); + private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis); // Convenience method to call removeNativeBinariesFromDirLI(File) public static void removeNativeBinariesLI(String nativeLibraryPath) { diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java index d1adfc95461d..158b526cb1a0 100644 --- a/core/java/com/android/internal/jank/Cuj.java +++ b/core/java/com/android/internal/jank/Cuj.java @@ -257,8 +257,16 @@ public class Cuj { */ public static final int CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU = 120; + /** Track Launcher Overview Task Dismiss animation. + * + * <p>Tracking starts when the overview task is dismissed via + * {@link com.android.quickstep.views.RecentsView#dismissTask}. Tracking finishes when the + * animation to dismiss the overview task ends. + */ + public static final int CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS = 121; + // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE. - @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU; + @VisibleForTesting static final int LAST_CUJ = CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS; /** @hide */ @IntDef({ @@ -370,7 +378,8 @@ public class Cuj { CUJ_DESKTOP_MODE_EXIT_MODE_ON_LAST_WINDOW_CLOSE, CUJ_DESKTOP_MODE_SNAP_RESIZE, CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW, - CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU + CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU, + CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS }) @Retention(RetentionPolicy.SOURCE) public @interface CujType {} @@ -493,6 +502,7 @@ public class Cuj { CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_SNAP_RESIZE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_SNAP_RESIZE; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_UNMAXIMIZE_WINDOW; CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU; + CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_OVERVIEW_TASK_DISMISS; } private Cuj() { @@ -729,6 +739,8 @@ public class Cuj { return "DESKTOP_MODE_UNMAXIMIZE_WINDOW"; case CUJ_DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU: return "DESKTOP_MODE_ENTER_FROM_OVERVIEW_MENU"; + case CUJ_LAUNCHER_OVERVIEW_TASK_DISMISS: + return "LAUNCHER_OVERVIEW_TASK_DISMISS"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index e0529b339d4a..6c00921ebb7b 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -184,6 +184,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private static final long ENFORCE_EDGE_TO_EDGE = 309578419; /** + * Disable opting out the edge-to-edge enforcement. + * {@link Build.VERSION_CODES#BAKLAVA} or above. + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.BAKLAVA) + private static final long DISABLE_OPT_OUT_EDGE_TO_EDGE = 377864165; + + /** * Override the layout in display cutout mode behavior. This will only apply if the edge to edge * is not enforced. */ @@ -450,7 +458,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { */ public static boolean isEdgeToEdgeEnforced(ApplicationInfo info, boolean local, TypedArray windowStyle) { - return !windowStyle.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false) + return !isOptingOutEdgeToEdgeEnforcement(info, local, windowStyle) && (info.targetSdkVersion >= ENFORCE_EDGE_TO_EDGE_SDK_VERSION || (Flags.enforceEdgeToEdge() && (local // Calling this doesn't require a permission. @@ -459,6 +467,29 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { : info.isChangeEnabled(ENFORCE_EDGE_TO_EDGE)))); } + /** + * Returns whether the given application is opting out edge-to-edge enforcement. + * + * @param info The application to query. + * @param local Whether this is called from the process of the given application. + * @param windowStyle The style of the window. + * @return {@code true} if the edge-to-edge enforcement is opting out. Otherwise, {@code false}. + */ + public static boolean isOptingOutEdgeToEdgeEnforcement(ApplicationInfo info, boolean local, + TypedArray windowStyle) { + final boolean disabled = Flags.disableOptOutEdgeToEdge() + // TODO (b/377864165): Don't exclude system apps after they are ready. + && !info.isSystemApp() + && (local + // Calling this doesn't require a permission. + ? CompatChanges.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE) + // Calling this requires permissions. + : info.isChangeEnabled(DISABLE_OPT_OUT_EDGE_TO_EDGE)); + return !disabled && windowStyle.getBoolean( + R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false /* default */); + + } + @Override public final void setContainer(Window container) { super.setContainer(container); @@ -2486,6 +2517,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { TypedArray a = getWindowStyle(); WindowManager.LayoutParams params = getAttributes(); + ApplicationInfo appInfo = getContext().getApplicationInfo(); if (false) { System.out.println("From style:"); @@ -2497,8 +2529,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { System.out.println(s); } - mEdgeToEdgeEnforced = isEdgeToEdgeEnforced( - getContext().getApplicationInfo(), true /* local */, a); + mEdgeToEdgeEnforced = isEdgeToEdgeEnforced(appInfo, true /* local */, a); if (mEdgeToEdgeEnforced) { getAttributes().privateFlags |= PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED; mDecorFitsSystemWindows = false; @@ -2507,8 +2538,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { // mNavigationBarColor is not reset here because it might be used to draw the scrim. } if (CompatChanges.isChangeEnabled(OVERRIDE_LAYOUT_IN_DISPLAY_CUTOUT_MODE) - && !a.getBoolean(R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, - false /* defValue */)) { + && !isOptingOutEdgeToEdgeEnforcement(appInfo, true /* local */, a)) { getAttributes().privateFlags |= PRIVATE_FLAG_OVERRIDE_LAYOUT_IN_DISPLAY_CUTOUT_MODE; } diff --git a/core/java/com/android/internal/widget/NotificationProgressBar.java b/core/java/com/android/internal/widget/NotificationProgressBar.java index 1b770207f2cb..0d3c470b0e8a 100644 --- a/core/java/com/android/internal/widget/NotificationProgressBar.java +++ b/core/java/com/android/internal/widget/NotificationProgressBar.java @@ -817,12 +817,13 @@ public final class NotificationProgressBar extends ProgressBar implements if (part instanceof Segment segment) { final float segWidth = segment.mFraction * totalWidth; // Advance the start position to account for a point immediately prior. - final float startOffset = getSegStartOffset(prevPart, pointRadius, segPointGap, x); + final float startOffset = getSegStartOffset(prevPart, pointRadius, segPointGap, + iPart == 1); final float start = x + startOffset; // Retract the end position to account for the padding and a point immediately // after. final float endOffset = getSegEndOffset(segment, nextPart, pointRadius, segPointGap, - segSegGap, x + segWidth, totalWidth, hasTrackerIcon); + segSegGap, iPart == nParts - 2, totalWidth, hasTrackerIcon); final float end = x + segWidth - endOffset; drawableParts.add(new DrawableSegment(start, end, segment.mColor, segment.mFaded)); @@ -840,10 +841,10 @@ public final class NotificationProgressBar extends ProgressBar implements // Only shift the points right at the start/end. // For the points close to the start/end, the segment minimum width requirement // would take care of shifting them to be within the bounds. - if (x == 0) { + if (iPart == 0) { start = 0; end = pointWidth; - } else if (x == totalWidth) { + } else if (iPart == nParts - 1) { start = totalWidth - pointWidth; end = totalWidth; } @@ -856,14 +857,14 @@ public final class NotificationProgressBar extends ProgressBar implements } private static float getSegStartOffset(Part prevPart, float pointRadius, float segPointGap, - float startX) { + boolean isSecondPart) { if (!(prevPart instanceof Point)) return 0F; - final float pointOffset = (startX == 0) ? pointRadius : 0; + final float pointOffset = isSecondPart ? pointRadius : 0; return pointOffset + pointRadius + segPointGap; } private static float getSegEndOffset(Segment seg, Part nextPart, float pointRadius, - float segPointGap, float segSegGap, float endX, float totalWidth, + float segPointGap, float segSegGap, boolean isSecondToLastPart, float totalWidth, boolean hasTrackerIcon) { if (nextPart == null) return 0F; if (nextPart instanceof Segment nextSeg) { @@ -874,7 +875,7 @@ public final class NotificationProgressBar extends ProgressBar implements return segSegGap; } - final float pointOffset = (endX == totalWidth) ? pointRadius : 0; + final float pointOffset = isSecondToLastPart ? pointRadius : 0; return segPointGap + pointRadius + pointOffset; } diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp index 3108f1f2c7c5..e78c5247d8a7 100644 --- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp +++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp @@ -349,21 +349,19 @@ static install_status_t copyFileIfChanged(JNIEnv* env, void* arg, ZipFileRO* zip * satisfied : * * - The entry is under the lib/ directory. - * - The entry name ends with ".so" and the entry name starts with "lib", - * an exception is made for debuggable apps. * - The entry filename is "safe" (as determined by isFilenameSafe). * */ class NativeLibrariesIterator { private: - NativeLibrariesIterator(ZipFileRO* zipFile, bool debuggable, void* cookie) - : mZipFile(zipFile), mDebuggable(debuggable), mCookie(cookie), mLastSlash(nullptr) { + NativeLibrariesIterator(ZipFileRO* zipFile, void* cookie) + : mZipFile(zipFile), mCookie(cookie), mLastSlash(nullptr) { fileName[0] = '\0'; } public: static base::expected<std::unique_ptr<NativeLibrariesIterator>, int32_t> create( - ZipFileRO* zipFile, bool debuggable) { + ZipFileRO* zipFile) { // Do not specify a suffix to find both .so files and gdbserver. auto result = zipFile->startIterationOrError(APK_LIB.data(), nullptr /* suffix */); if (!result.ok()) { @@ -371,7 +369,7 @@ public: } return std::unique_ptr<NativeLibrariesIterator>( - new NativeLibrariesIterator(zipFile, debuggable, result.value())); + new NativeLibrariesIterator(zipFile, result.value())); } base::expected<ZipEntryRO, int32_t> next() { @@ -390,7 +388,7 @@ public: continue; } - const char* lastSlash = util::ValidLibraryPathLastSlash(fileName, false, mDebuggable); + const char* lastSlash = util::ValidLibraryPathLastSlash(fileName, false); if (lastSlash) { mLastSlash = lastSlash; break; @@ -415,20 +413,19 @@ private: char fileName[PATH_MAX]; ZipFileRO* const mZipFile; - const bool mDebuggable; void* mCookie; const char* mLastSlash; }; static install_status_t iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi, - jboolean debuggable, iterFunc callFunc, void* callArg) { + iterFunc callFunc, void* callArg) { ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle); if (zipFile == nullptr) { return INSTALL_FAILED_INVALID_APK; } - auto result = NativeLibrariesIterator::create(zipFile, debuggable); + auto result = NativeLibrariesIterator::create(zipFile); if (!result.ok()) { return INSTALL_FAILED_INVALID_APK; } @@ -470,14 +467,13 @@ iterateOverNativeFiles(JNIEnv *env, jlong apkHandle, jstring javaCpuAbi, return INSTALL_SUCCEEDED; } -static int findSupportedAbi(JNIEnv* env, jlong apkHandle, jobjectArray supportedAbisArray, - jboolean debuggable) { +static int findSupportedAbi(JNIEnv* env, jlong apkHandle, jobjectArray supportedAbisArray) { ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle); if (zipFile == nullptr) { return INSTALL_FAILED_INVALID_APK; } - auto result = NativeLibrariesIterator::create(zipFile, debuggable); + auto result = NativeLibrariesIterator::create(zipFile); if (!result.ok()) { return INSTALL_FAILED_INVALID_APK; } @@ -548,26 +544,26 @@ com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, { jboolean app_compat_16kb = app_compat_16kb_enabled(); void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable, &app_compat_16kb }; - return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable, + return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, copyFileIfChanged, reinterpret_cast<void*>(args)); } static jlong com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env, jclass clazz, - jlong apkHandle, jstring javaCpuAbi, jboolean debuggable) + jlong apkHandle, jstring javaCpuAbi) { size_t totalSize = 0; - iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable, sumFiles, &totalSize); + iterateOverNativeFiles(env, apkHandle, javaCpuAbi, sumFiles, &totalSize); return totalSize; } static jint com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz, - jlong apkHandle, jobjectArray javaCpuAbisToSearch, jboolean debuggable) + jlong apkHandle, jobjectArray javaCpuAbisToSearch) { - return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable); + return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch); } enum bitcode_scan_result_t { @@ -748,7 +744,7 @@ static jint com_android_internal_content_NativeLibraryHelper_checkApkAlignment( return PAGE_SIZE_APP_COMPAT_FLAG_ERROR; } - auto result = NativeLibrariesIterator::create(zipFile, debuggable); + auto result = NativeLibrariesIterator::create(zipFile); if (!result.ok()) { ALOGE("Can't iterate over native libs for file:%s", zipFile->getZipFileName()); return PAGE_SIZE_APP_COMPAT_FLAG_ERROR; @@ -810,9 +806,9 @@ static const JNINativeMethod gMethods[] = { {"nativeClose", "(J)V", (void*)com_android_internal_content_NativeLibraryHelper_close}, {"nativeCopyNativeBinaries", "(JLjava/lang/String;Ljava/lang/String;ZZ)I", (void*)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries}, - {"nativeSumNativeBinaries", "(JLjava/lang/String;Z)J", + {"nativeSumNativeBinaries", "(JLjava/lang/String;)J", (void*)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries}, - {"nativeFindSupportedAbi", "(J[Ljava/lang/String;Z)I", + {"nativeFindSupportedAbi", "(J[Ljava/lang/String;)I", (void*)com_android_internal_content_NativeLibraryHelper_findSupportedAbi}, {"hasRenderscriptBitcode", "(J)I", (void*)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode}, diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index 0eb7c4aee287..5225ce878310 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -51,7 +51,8 @@ static const char* kPathAllowlist[] = { "/dev/blkio/tasks", "/metadata/aconfig/maps/system.package.map", "/metadata/aconfig/maps/system.flag.map", - "/metadata/aconfig/boot/system.val" + "/metadata/aconfig/boot/system.val", + "/metadata/libprocessgroup/memcg_v2_max_activation_depth" // TODO Revert after go/android-memcgv2-exp b/386797433 }; static const char kFdPath[] = "/proc/self/fd"; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 445080215017..73279700ecb1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -180,6 +180,7 @@ <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" /> <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> <protected-broadcast android:name="android.bluetooth.device.action.KEY_MISSING" /> + <protected-broadcast android:name="android.bluetooth.device.action.ENCRYPTION_CHANGE" /> <protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" /> <protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" /> <protected-broadcast android:name="android.bluetooth.device.action.REMOTE_ISSUE_OCCURRED" /> diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml index 44a5df9b60be..c43975e4ad3c 100644 --- a/core/res/res/layout/preference_list_fragment.xml +++ b/core/res/res/layout/preference_list_fragment.xml @@ -19,7 +19,6 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" - android:fitsSystemWindows="true" android:layout_height="match_parent" android:layout_width="match_parent" android:background="@android:color/transparent" diff --git a/core/res/res/layout/preference_list_fragment_material.xml b/core/res/res/layout/preference_list_fragment_material.xml index 4df76029e606..db2fe7d038e0 100644 --- a/core/res/res/layout/preference_list_fragment_material.xml +++ b/core/res/res/layout/preference_list_fragment_material.xml @@ -19,7 +19,6 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" - android:fitsSystemWindows="true" android:layout_height="match_parent" android:layout_width="match_parent" android:background="@android:color/transparent" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 1578bc23dfe8..59414771c36c 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan nie selnetwerk bereik nie"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer die voorkeurnetwerk verander. Tik om te verander."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepe is onbeskikbaar"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Moenie weer wys nie"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Noodoproepe vereis ’n selnetwerk."</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Opletberigte"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Oproepaanstuur"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Netwerkwaarskuwings"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Netwerk is beskikbaar"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Tyd en tydsones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Opletberigte van jou IT-admin af"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Opletberigte"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Kleinhandeldemonstrasie"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App loop tans"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programme wat batterykrag gebruik"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergroting"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Gehoortoestel"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Toeganklikheidgebruik"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skerm"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans batterykrag"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laai app af"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nuwe SIM is ingesit"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tik om dit op te stel"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Jou tydsone het verander"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Jy is nou in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Stel tyd"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Stel datum"</string> <string name="date_time_set" msgid="4603445265164486816">"Stel"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Eenhandmodus"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra donker"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Gehoortoestelle"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ontkoppel"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Gekoppel"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktief"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Laai tans"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Los die volumesleutels. Druk en hou albei volumesleutels weer 3 sekondes lank in om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aan te skakel."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 2 vingers op en los vinnig."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 3 vingers op en los vinnig."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Skakel oor na foonmikrofoon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Skakel oor na gehoortoestelmikrofoon?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Vir beter klank of as jou gehoortoestel se battery laag is. Dit skakel net jou mikrofoon tydens die oproep oor."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Jy kan jou gehoortoestel en mikrofoon vir handvrye oproepe gebruik. Dit skakel net jou mikrofoon tydens die oproep oor."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skakel oor"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Instellings"</string> <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string> <string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Meld <xliff:g id="NAME">%1$s</xliff:g> tans af …"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Appinhoud is weens sekuriteit van skermdeling verberg"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Outomaties aan satelliet gekoppel"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Jy kan boodskappe stuur en ontvang sonder ’n selfoon- of wi-fi-netwerk"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Gebruik satellietboodskappe?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Stuur en ontvang boodskappe sonder ’n selfoon- of wi-fi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 114013007fbe..0ca5ab4a338d 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"የሞባይል አውታረ መረብን መድረስ አልተቻለም"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ተመራጭ አውታረ መረብን ለመለወጥ ይሞክሩ። ለመለወጥ መታ ያድርጉ።"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"የአደጋ ጊዜ ጥሪ አይገኝም"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ዳግም አታሳይ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"የአደጋ ጥሪዎች የተንቀሳቃሽ ስልክ አውታረ መረብ ያስፈልጋቸዋል"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ማንቂያዎች"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ጥሪ ማስተላለፍ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"የአውታረ መረብ ማንቂያዎች"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"አውታረ መረብ ይገኛል"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"የቪፒኤን ሁኔታ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ጊዜ እና የሰዓት ሰቆች"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ከእርስዎ አይቲ አስተዳዳሪ የመጡ ማንቂያዎች"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ማንቂያዎች"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"የችርቻሮ ማሳያ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP እየሠራ ነው"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ባትሪ በመፍጀት ላይ ያሉ መተግበሪያዎች"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ማጉላት"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"የመስማት ችሎታ መሣሪያ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"የተደራሽነት አጠቃቀም"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ማሳያ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ባትሪ እየተጠቀመ ነው"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"መተግበሪያን አውርድ"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"አዲስ ሲም ገብቷል"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ለማዋቀር መታ ያድርጉ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"የእርስዎ የሰዓት ሰቅ ተለውጧል"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"አሁን <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ውስጥ ነዎት"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ጊዜ አዘጋጅ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ውሂብ አዘጋጅ"</string> <string name="date_time_set" msgid="4603445265164486816">"አዘጋጅ"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"የአንድ እጅ ሁነታ"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ተጨማሪ ደብዛዛ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"የመስሚያ መሣሪያዎች"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ግንኙነት ተቋርጧል"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"ተገናኝቷል"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ገቢር"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"በመጫን ላይ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"የድምጽ መጠን ቁልፎቹን ይልቀቁ። <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለማብራት ሁለቱንም የድምጽ መጠን ቁልፎች በድጋሚ ለ3 ሰከንዶች ተጭነው ይያዙ።"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች በ2 ጣቶች ወደላይ ያንሸራትቱ እና በፍጥነት ይልቀቁ።"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች ወደላይ በ3 ጣቶች ያንሸራትቱ እና ወዲያው ይልቀቁ።"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ማጉላት"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ወደ ስልክ ማይክሮፎን ይቀየር?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ወደ መስሚያ አጋዥ መሣሪያ ማይክሮፎን ይቀየር?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"የተሻለ ድምፅ ለማግኘት ወይም መስሚያ አጋዥ መሣሪያዎ ባትሪ ዝቅተኛ ከሆነ። ይህ በጥሪው ወቅት ማይክሮፎንዎን ብቻ ይቀይራል።"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"የእርስዎን መስሚያ አጋዥ መሣሪያ ማይክሮፎን ለነጻ እጅ መደወል መጠቀም ይችላሉ። ይህ በጥሪው ወቅት ማይክሮፎንዎን ብቻ ይቀይራል።"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ቀይር"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ቅንብሮች"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ለደኅንነት ሲባል የመተግበሪያ ይዘት ከማያ ገጽ ማጋራት ተደብቋል"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ከሳተላይት ጋር በራስ-ሰር ተገናኝቷል"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ያለ ሞባይል ወይም የWi-Fi አውታረ መረብ መልዕክቶችን መላክ እና መቀበል ይችላሉ"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"የሳተላይት መልዕክት መላላክን ይጠቀማሉ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ያለ ሞባይል ወይም የWi-Fi አውታረ መረብ መልዕክቶችን ይላኩ እና ይቀበሉ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"መልዕክቶች ይክፈቱ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 02e5be1a36b1..cb765e71b801 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -91,8 +91,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"يتعذّر الوصول إلى شبكة الجوّال."</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"حاول تغيير الشبكة المفضلة. انقر لتغييرها."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"لا تتوفر إمكانية الاتصال في حالات الطوارئ."</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"عدم عرض هذا الإشعار مجددًا"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"يتطلّب إجراء مكالمات الطوارئ الاتصال بشبكة جوّال"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"التنبيهات"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"إعادة توجيه المكالمة"</string> @@ -307,6 +306,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"تنبيهات الشبكة"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"الشبكة متوفرة"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"حالة شبكة VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"الوقت والمناطق الزمنية"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"التنبيهات من مشرف تكنولوجيا المعلومات"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"التنبيهات"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"عرض توضيحي لبائع التجزئة"</string> @@ -314,6 +314,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"التطبيق قيد التشغيل"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"التطبيقات التي تستهلك البطارية"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"التكبير"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"سماعة الأذن الطبية"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"استخدام \"أدوات تسهيل الاستخدام\""</string> <string name="notification_channel_display" msgid="6905032605735615090">"الشاشة"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"يستخدم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> البطارية"</string> @@ -1411,6 +1412,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"تنزيل التطبيق"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"تم إدخال شريحة SIM جديدة."</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"انقر لإعداده."</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"تم تغيير منطقتك الزمنية"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"أنت الآن في <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ضبط الوقت"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"تعيين التاريخ"</string> <string name="date_time_set" msgid="4603445265164486816">"ضبط"</string> @@ -1784,14 +1787,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"وضع \"التصفح بيد واحدة\""</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"زيادة تعتيم الشاشة"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعات الأذن الطبية"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"غير متّصل"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"متّصل"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"متّصل حاليًا"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"غير متاح بعد"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ارفع إصبعَيك عن مفتاحَي مستوى الصوت. لتفعيل خدمة \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"، اضغط مع الاستمرار على كلا مفتاحَي مستوى الصوت مجددًا لمدة 3 ثوانٍ."</string> @@ -1802,6 +1801,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعَين وارفعما بعدها بسرعة."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام 3 أصابع وارفع أصابعك بعدها بسرعة."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"التكبير"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"هل المطلوب التبديل إلى ميكروفون الهاتف؟"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"هل المطلوب التبديل إلى ميكروفون سماعة الأذن الطبية؟"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ننصحك بالتبديل إذا أردت الحصول على صوت أفضل أو عند انخفاض طاقة بطارية سماعة الأذن الطبية. يؤدي هذا الإجراء إلى تبديل الميكروفون فقط أثناء المكالمة."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"يمكنك استخدام ميكروفون سماعة الأذن الطبية لإجراء مكالمات بدون لمس الجهاز. يؤدي هذا الإجراء إلى تبديل الميكروفون فقط أثناء المكالمة."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"تبديل"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"الإعدادات"</string> <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> @@ -2458,6 +2463,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"تم إخفاء محتوى التطبيق بعد تفعيل ميزة \"مشاركة الشاشة\" للحفاظ على أمانك"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"تم الاتصال تلقائيًا بالقمر الصناعي"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"يمكنك إرسال الرسائل واستلامها بدون شبكة الجوّال أو شبكة Wi-Fi."</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"هل تريد المراسلة عبر القمر الصناعي؟"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"يمكنك إرسال الرسائل واستلامها بدون شبكة الجوّال أو شبكة Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"فتح تطبيق \"الرسائل\""</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 9f3b263f84a6..48895bc41000 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ম’বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পচন্দৰ নেটৱৰ্ক সলনি কৰি চেষ্টা কৰি চাওক। সলনি কৰিবলৈ টিপক।"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"পুনৰাই নেদেখুৱাব"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"জৰুৰীকালীন কল কৰিবলৈ ম’বাইল নেটৱৰ্কৰ প্ৰয়োজন"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"সতৰ্কবাণীসমূহ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফৰৱাৰ্ডিং"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"নেটৱৰ্ক সম্পৰ্কীয় সতৰ্কবাণী"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"নেটৱৰ্ক উপলব্ধ"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"ভিপিএনৰ স্থিতি"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"সময় আৰু সময় মণ্ডল"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"আপোনাৰ আইটি প্ৰশাসকৰ পৰা অহা সতৰ্কবাণী"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"সতৰ্কবাণীসমূহ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"খুচুৰা ডেম\'"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"এপ্ চলি আছে"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"বেটাৰী খৰচ কৰা এপ্সমূহ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"বিবৰ্ধন"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"শুনাৰ ডিভাইচ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"সাধ্য সুবিধাৰ ব্যৱহাৰ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ডিছপ্লে’"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ বেটাৰী ব্যৱহাৰ কৰি আছে"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"এপ্ ডাউনল’ড কৰক"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"নতুন ছিম ভৰোৱা হৈছে"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ছেট আপ কৰিবলৈ টিপক"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"আপোনাৰ সময় মণ্ডল সলনি হৈছে"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"আপুনি এতিয়া <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g>ত (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) আছে"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"সময় ছেট কৰক"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"তাৰিখ ছেট কৰক"</string> <string name="date_time_set" msgid="4603445265164486816">"ছেট কৰক"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এখন হাতেৰে ব্যৱহাৰ কৰাৰ ম’ড"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিৰিক্তভাৱে পোহৰ কমোৱাৰ সুবিধা"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"শুনাৰ ডিভাইচ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"সংযোগ বিচ্ছিন্ন হ’ল"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"সংযোগ কৰা হ’ল"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"সক্ৰিয় হৈ আছে"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ল’ড হৈ আছে"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম কী এৰি দিয়ক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰিবলৈ, দুয়োটা ভলিউম কী পুনৰ ৩ ছেকেণ্ডৰ বাবে টিপি হেঁচি ৰাখক।"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ২ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ৩ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বিবৰ্ধন"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ফ’নৰ মাইকলৈ সলনি কৰিবনে?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"শ্ৰৱণ যন্ত্ৰৰ মাইকলৈ সলনি কৰিবনে?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"অধিক ভাল ধ্বনিৰ বাবে বা যদি আপোনাৰ শ্ৰৱণ যন্ত্ৰৰ বেটাৰীৰ চাৰ্জ কম থাকে। এইটোৱে কল চলি থাকোঁতে কেৱল আপোনাৰ মাইকটো সলনি কৰে।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"আপুনি হেণ্ডছ্-ফ্ৰী কলিঙৰ বাবে আপোনাৰ শ্ৰৱণ যন্ত্ৰৰ মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰিব পাৰে। এইটোৱে কল চলি থাকোঁতে কেৱল আপোনাৰ মাইকটো সলনি কৰে।"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"সলনি কৰক"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ছেটিং"</string> <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> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"সুৰক্ষাৰ বাবে এপৰ সমল স্ক্ৰীণ শ্বেয়াৰ কৰাৰ পৰা লুকুৱাই ৰখা হৈছে"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"উপগ্ৰহৰ সৈতে স্বয়ংক্ৰিয়ভাৱে সংযুক্ত হৈছে"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"আপুনি ম’বাইল বা ৱাই-ফাই নেটৱৰ্কৰ জৰিয়তে পাঠ বাৰ্তা পঠিয়াব বা লাভ কৰিব পাৰে"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"আপুনি উপগ্ৰহৰ জৰিয়তে বাৰ্তা পঠিয়াব আৰু গ্ৰহণ কৰিব পাৰে আৰু সীমিত তথ্য ব্যৱহাৰ কৰিব পাৰে"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"উপগ্ৰহৰ জৰিয়তে বাৰ্তা বিনিময়ৰ সুবিধাটো ব্যৱহাৰ কৰিবনে?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"আপুনি কোনো ম’বাইল বা ৱাই-ফাই নেটৱৰ্ক নোহোৱাকৈ বাৰ্তা পঠিয়াওক আৰু লাভ কৰক"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 54062de9536b..0a4597ec589e 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil şəbəkəyə daxil olmaq mümkün deyil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tərcih edilən şəbəkəni dəyişin. Dəyişmək üçün klikləyin."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Təcili zəng əlçatan deyil"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Yenidən göstərməyin"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Təcili zənglər üçün mobil şəbəkə tələb olunur"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Siqnallar"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Zəng yönləndirmə"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Şəbəkə siqnalları"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Şəbəkə əlçatandır"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN statusu"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Vaxt və saat qurşaqları"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT adminindən xəbərdarlıqlar"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Siqnallar"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Pərakəndə demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Tətbiq işləyir"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Batareyadan istifadə edən tətbiqlər"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Böyütmə"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Eşitmə cihazı"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Əlçatımlılıq istifadəsi"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Displey"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> batareyadan istifadə edir"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Tətbiqi endirin"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Yeni SIM kart taxılıb"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Quraşdırmaq üçün tıklayın"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Saat qurşağınız dəyişildi"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Hazırda saat qurşağınız: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Vaxt ayarlayın"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Tarixi quraşdır"</string> <string name="date_time_set" msgid="4603445265164486816">"Ayarlayın"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Birəlli rejim"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Əlavə tündləşmə"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eşitmə cihazları"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Bağlantı kəsildi"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Qoşuldu"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivdir"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Yüklənir"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Səs düymələrini buraxın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etmək üçün hər iki səs düyməsinə yenidən 3 saniyə basıb saxlayın."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 2 barmaq ilə yuxarı çəkin və tez buraxın."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 3 barmaq ilə yuxarı çəkin və tez buraxın."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Böyütmə"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofonuna dəyişilsin?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eşitmə aparatı mikrofonuna dəyişdirilsin?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha yaxşı səs üçün və ya eşitmə aparatınızın batareyası azdırsa. Bu, yalnız zəng zamanı mikrofonu dəyişdirir."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Səsli idarəetmə ilə zəng etmək üçün eşitmə aparatı mikrofonunuzdan istifadə edə bilərsiniz. Bu, yalnız zəng zamanı mikrofonu dəyişdirir."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Dəyişin"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string> <string name="user_switched" msgid="7249833311585228097">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> çıxır..."</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Tətbiq kontenti güvənlik məsələlərinə görə ekran paylaşımından gizlədildi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Peyk mesajlaşmasından istifadə edilsin?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesajlar göndərin və qəbul edin"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 69b46124cec1..5fb744ee2fa9 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Povezivanje sa mobilnom mrežom nije uspelo"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne prikazuj ponovo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Hitni pozivi zahtevaju mobilnu mrežu"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Obaveštenja u vezi sa mrežom"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Vreme i vremenske zone"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Obaveštenja od IT administratora"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozorenja"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Režim demonstracije za maloprodajne objekte"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećanje"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Slušni aparat"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Korišćenje Pristupačnosti"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Preuzmite aplikaciju"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nova SIM kartica je umetnuta"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite za podešavanje"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vremenska zona je promenjena"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sada ste u vremenskoj zoni <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Podesite vreme"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Podešavanje datuma"</string> <string name="date_time_set" msgid="4603445265164486816">"Podesi"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednom rukom"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamni"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Veza je prekinuta"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Učitava se"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tastere za jačinu zvuka. Da biste uključili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite oba tastera za jačinu zvuka 3 sekunde."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 2 prsta i brzo pustite."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 3 prsta i brzo pustite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite da pređete na mikrofon telefona?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite da pređete na mikrofon slušnog aparata?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za bolji zvuk ili ako je baterija slušnog aparata skoro prazna. Time se mikrofon menja samo tokom poziva."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Možete da koristite mikrofon slušnog aparata za hendsfri pozivanje. Time se mikrofon menja samo tokom poziva."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Promeni"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Podešavanja"</string> <string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljuje se <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije je skriven za deljenje sadržaja ekrana zbog bezbednosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete da šaljete i primate poruke bez mobilne ili WiFi mreže"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Želite da koristite satelitsku razmenu poruka?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 9f7f823fdec0..74c0b46a8045 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Сетка мабільнай сувязі недаступная"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Націсніце, каб выбраць іншую сетку."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстранныя выклікі недаступныя"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Больш не паказваць"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Для экстранных выклікаў патрабуецца мабільная сетка"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Абвесткі"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Пераадрасацыя выкліку"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Абвесткі сеткі"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Сетка даступная"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Стан VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Час і часавыя паясы"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Абвесткі ад IT-адміністратара"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Абвесткi"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Дэманстрацыйны рэжым для пунктаў продажу"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Праграма працуе"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Праграмы, якія выкарыстоўваюць акумулятар"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Павелічэнне"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Слыхавы апарат"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Выкарыстанне спецыяльных магчымасцей"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Дысплэй"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> выкарыстоўвае акумулятар"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Спампаваць праграму"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Устаўлена новая SIM-карта"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Краніце, каб наладзіць"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Ваш часавы пояс зменены"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ваш часавы пояс: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Задаць час"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Задаць дату"</string> <string name="date_time_set" msgid="4603445265164486816">"Задаць"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Рэжым кіравання адной рукой"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дадатковае памяншэнне яркасці"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слыхавыя апараты"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Адключана"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Падключана"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Актыўная"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Ідзе загрузка"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Адпусціце клавішы гучнасці. Каб уключыць сэрвіс \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце абедзве клавішы гучнасці яшчэ раз і ўтрымлівайце іх на працягу 3 секунд."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце двума пальцамі ад нізу экрана ўверх і хутка адпусціце."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце трыма пальцамі ад нізу экрана ўверх і хутка адпусціце."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Павелічэнне"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Пераключыцца на мікрафон тэлефона?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Пераключыцца на мікрафон слыхавога апарата?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Для паляпшэння якасці гуку або пры нізкім узроўні зараду акумулятара слыхавога апарата. Будзе пераключаны толькі ваш мікрафон."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Вы можаце выкарыстоўваць мікрафон слыхавога апарата, каб размаўляць падчас званка без дапамогі рук. Будзе пераключаны толькі ваш мікрафон."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Пераключыцца"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Налады"</string> <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> @@ -2456,6 +2461,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Змесціва праграмы выключана з абагульвання экрана ў мэтах бяспекі"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Аўтаматычна падключана да сістэм спадарожнікавай сувязі"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можаце адпраўляць і атрымліваць паведамленні без доступу да мабільнай сеткі або Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Выкарыстоўваць абмен паведамленнямі па спадарожнікавай сувязі?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Вы можаце адпраўляць і атрымліваць паведамленні, калі падключэнне да мабільнай сеткі або сеткі Wi-Fi адсутнічае"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Адкрыць Паведамленні"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 1353d2287c09..b857fb52b418 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не може да се установи връзка с мобилната мрежа"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Изберете друга предпочитана мрежа. Докоснете за промяна."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Няма достъп до спешните обаждания"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Да не се показва отново"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"За спешните обаждания се изисква мобилна мрежа"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сигнали"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Пренасочване на обаждания"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Сигнали за мрежата"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Налице е мрежа"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Състояние на VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Час и часови зони"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Сигнали от системния ви администратор"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Сигнали"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Демонстрационен режим за магазини"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Приложението работи"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Приложения, използващи батерията"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увеличение"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Слухов апарат"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Използване на услугите за достъпност"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Дисплей"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> използва батерията"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Изтегляне на приложението"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Поставена е нова SIM карта"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Докоснете, за да я настроите"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Часовата ви зона се промени"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Вече сте в зоната <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Задаване на часа"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Задаване на дата"</string> <string name="date_time_set" msgid="4603445265164486816">"Задаване"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Работа с една ръка"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Допълнително затъмняване"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухови апарати"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Няма връзка"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Свързано"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Зарежда се"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Освободете бутоните за силата на звука. За да включите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, отново натиснете двата бутона за силата на звука и задръжте за 3 секунди."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 2 пръста нагоре от долната част на екрана и бързо освободете."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 3 пръста нагоре от долната част на екрана и бързо освободете."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Да се превключи ли към микрофона на телефона?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Да се превключи ли към микрофона на слуховия апарат?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"За по-добър звук или ако батерията на слуховия ви апарат е изтощена. Микрофонът ще бъде включен само по време на обаждането."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Можете да използвате микрофона на слуховия си апарат за обаждания в режим „свободни ръце“. Микрофонът ще бъде включен само по време на обаждането."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Превключване"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Настройки"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Съдържанието на приложението е скрито от функцията за споделяне на екрана от съображения за сигурност"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматично установена връзка със сателит"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да изпращате и получавате съобщения без мобилна или Wi-Fi мрежа"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Да се използват ли сателитни съобщения?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Изпращайте и получавайте съобщения без мобилна или Wi-Fi мрежа"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отваряне на Messages"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index d74a3a375159..8da67849c84d 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"মোবাইল নেটওয়ার্কে কানেক্ট করা যাচ্ছে না"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পছন্দের নেটওয়ার্ক পরিবর্তন করে দেখুন। অন্য নেটওয়ার্ক বেছে নিতে ট্যাপ করুন।"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জরুরি কল করা যাবে না"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"আর দেখতে চাই না"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"জরুরি কলের জন্য মোবাইল নেটওয়ার্ক থাকতে হবে"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"সতর্কতা"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফরওয়ার্ড করা"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"নেটওয়ার্ক সক্রান্ত অ্যালার্ট"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"নেটওয়ার্ক পাওয়া যাচ্ছে"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN এর স্থিতি"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"সময় এবং টাইম জোন"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"আপনার আইটি অ্যাডমিনের সতর্কতা"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"সতর্কতা"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"খুচরা বিক্রয়ের ডেমো"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"অ্যাপ চলছে"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"কিছু অ্যাপ ব্যাটারি ব্যবহার করছে"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"বড় করে দেখা"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"হিয়ারিং ডিভাইস"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"অ্যাক্সেসিবিলিটি সংক্রান্ত ব্যবহার"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ডিসপ্লে"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপটি ব্যাটারি ব্যবহার করছে"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"অ্যাপ ডাউনলোড করুন"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"নতুন সিম ঢোকানো হয়েছে"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"এটিকে সেট-আপ করতে আলতো চাপুন"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"আপনার টাইম জোন পরিবর্তন হয়ে গেছে"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"আপনি এখন <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)-এ আছেন"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"সময় সেট করুন"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"তারিখ সেট করুন"</string> <string name="date_time_set" msgid="4603445265164486816">"সেট করুন"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"এক হাতে ব্যবহার করার মোড"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"অতিরিক্ত কম উজ্জ্বলতা"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"হিয়ারিং ডিভাইস"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ডিসকানেক্ট হয়ে গেছে"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"কানেক্ট করা হয়েছে"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"অ্যাক্টিভ"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"লোড হচ্ছে"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম \'কী\' রিলিজ করুন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করুন, দু\'টি ভলিউম \'কী\' আবার প্রেস করে ৩ সেকেন্ড ধরে রাখুন।"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ২টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ৩টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বড় করে দেখা"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ফোনের মাইকে পরিবর্তন করবেন?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"হিয়ারিং এড মাইকে পরিবর্তন করবেন?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"আরও ভালো সাউন্ডের জন্য অথবা আপনার হিয়ারিং এডের ব্যাটারি যদি কম থাকে। এটি শুধুমাত্র কল চলাকালীন আপনার মাইক পরিবর্তন করে।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"হ্যান্ডস-ফ্রি কলিংয়ের জন্য আপনার হিয়ারিং এডের মাইক্রোফোন ব্যবহার করতে পারবেন। এটি শুধুমাত্র কল চলাকালীন আপনার মাইক পরিবর্তন করে।"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"পরিবর্তন করুন"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"সেটিংস"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"নিরাপত্তার জন্য স্ক্রিন শেয়ার করা থেকে লুকানো অ্যাপের কন্টেন্ট"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"স্যাটেলাইটের সাথে অটোমেটিক কানেক্ট করা হয়েছে"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"আপনি কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠাতে ও পেতে পারবেন"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"\'স্যাটেলাইট মেসেজিং\' ব্যবহার করবেন?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠান ও রিসিভ করুন"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index c9168709eb08..639972915f76 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nije moguće dosegnuti mobilnu mrežu"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite za promjenu."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi su nedostupni"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne prikazuj ponovo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za hitne pozive potrebna je mreža"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Prosljeđivanje poziva"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Mrežna upozorenja"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Vrijeme i vremenske zone"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Upozorenja od IT administratora"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozorenja"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Prodajna demonstracija"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Pokrenuta aplikacija"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije koje troše bateriju"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Uvećavanje"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Slušni aparat"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Korištenje pristupačnosti"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> troši bateriju"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Preuzmite aplikaciju"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nova SIM kartica je umetnuta"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite da biste postavili"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vremenska zona je promijenjena"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sada ste u vremenskoj zoni <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Postavljanje vremena"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Postavljanje datuma"</string> <string name="date_time_set" msgid="4603445265164486816">"Postaviti"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatno zatamnjenje"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nije povezano"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Učitavanje"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za jačinu zvuka. Da uključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za jačinu zvuka 3 sekunde."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 2 prsta s dna ekrana i brzo pustite."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 3 prsta s dna ekrana i brzo pustite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećavanje"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Promijeniti na mikrofon telefona?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Promijeniti na mikrofon slušnog aparata?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za bolji zvuk ili ako je baterija slušnog aparata slaba. Ovo mijenja mikrofon samo tokom poziva."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Možete koristiti mikrofon slušnog aparata za pozivanje bez dodira. Ovo mijenja mikrofon samo tokom poziva."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Promijeni"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string> <string name="user_switched" msgid="7249833311585228097">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije je sakriven od dijeljenja ekrana radi sigurnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski je povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne ili WiFi mreže"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Koristiti satelitsku razmjenu poruka?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke bez mobilne ili WiFi mreže"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 5c53857c5902..49d80c25cbfc 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No es pot accedir a la xarxa mòbil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova de canviar de xarxa preferent. Toca per canviar-la."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Les trucades d\'emergència no estan disponibles"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"No ho tornis a mostrar"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per poder fer trucades d\'emergència, cal tenir connexió de xarxa mòbil"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desviació de trucades"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertes de xarxa"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Hi ha una xarxa disponible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Estat de la VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora i zones horàries"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertes de l\'administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertes"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demostració per a botigues"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicació en execució"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicacions que consumeixen bateria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliació"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Audiòfon"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Ús de les funcions d\'accessibilitat"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Pantalla"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> està consumint bateria"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Baixa l\'aplicació"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"S\'ha inserit una SIM nova"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toca per configurar-la"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"La zona horària ha canviat"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ara ets a <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Defineix l\'hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Establiment de data"</string> <string name="date_time_set" msgid="4603445265164486816">"Defineix"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode d\'una mà"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuació extra"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audiòfons"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconnectat"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connectat"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Actiu"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"S\'està carregant"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Deixa anar les tecles de volum. Per activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, torna a mantenir premudes totes dues tecles de volum durant 3 segons."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 2 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 3 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliació"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vols canviar al micròfon del telèfon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vols canviar al micròfon de l\'audiòfon?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per obtenir un so millor o si l\'audiòfon té poca bateria. Aquesta opció només canvia el micròfon durant la trucada."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pots fer servir el micròfon del teu audiòfon per fer trucades amb mans lliures. Aquesta opció només canvia el micròfon durant la trucada."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Canvia"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuració"</string> <string name="user_switched" msgid="7249833311585228097">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"S\'està tancant la sessió de l\'usuari <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per seguretat"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Vols utilitzar els missatges per satèl·lit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envia i rep missatges sense una xarxa mòbil o Wi‑Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 8d595d893ead..8b45d72f9131 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilní síť není dostupná"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Zkuste změnit preferovanou síť. Změníte ji klepnutím."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tísňová volání jsou nedostupná"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Už nezobrazovat"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Tísňová volání vyžadují mobilní síť"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornění"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Přesměrování hovorů"</string> @@ -305,6 +304,8 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Síťová upozornění"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"K dispozici je síť"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stav sítě VPN"</string> + <!-- no translation found for notification_channel_system_time (1660313368058030441) --> + <skip /> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Upozornění od vašeho administrátora IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozornění"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Prodejní ukázka"</string> @@ -312,6 +313,8 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikace je spuštěna"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikace spotřebovávají baterii"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zvětšení"</string> + <!-- no translation found for notification_channel_accessibility_hearing_device (7816963856388758952) --> + <skip /> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Využití přístupnosti"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Displej"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> využívá baterii"</string> @@ -1409,6 +1412,10 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Stáhnout aplikaci"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Byla vložena nová SIM karta"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Klepnutím zahájíte nastavení"</string> + <!-- no translation found for time_zone_change_notification_title (5232503069219193218) --> + <skip /> + <!-- no translation found for time_zone_change_notification_body (6135793674904665585) --> + <skip /> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Nastavit čas"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Nastavení data"</string> <string name="date_time_set" msgid="4603445265164486816">"Nastavit"</string> @@ -1782,14 +1789,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jedné ruky"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Velmi tmavé zobrazení"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Naslouchátka"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Odpojeno"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Připojeno"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivní"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Načítání"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvolněte tlačítka hlasitosti. Pokud chcete zapnout službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znovu tři sekundy podržte obě tlačítka hlasitosti."</string> @@ -1800,6 +1803,18 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkce se otevře při příštím použití této zkratky. Přejeďte dvěma prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkce se otevře při příštím použití této zkratky. Přejeďte třemi prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zvětšení"</string> + <!-- no translation found for hearing_device_switch_phone_mic_notification_title (6645178038359708836) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_title (4612074852145289569) --> + <skip /> + <!-- no translation found for hearing_device_switch_phone_mic_notification_text (1332426273666077412) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_text (8288368365767284208) --> + <skip /> + <!-- no translation found for hearing_device_notification_switch_button (3619524619430941300) --> + <skip /> + <!-- no translation found for hearing_device_notification_settings_button (6673651052880279178) --> + <skip /> <string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Odhlašování uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2456,6 +2471,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikace je z bezpečnostních důvodů při sdílení obrazovky skryt"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky připojeno k satelitu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Zprávy můžete odesílat a přijímat bez mobilní sítě nebo sítě Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Použít satelitní zprávy?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Odesílejte a přijímejte zprávy bez mobilní sítě nebo Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 66e3402c1ebf..edd910c9fe6d 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Der er ingen forbindelse til mobilnetværket"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv at skifte dit foretrukne netværk. Tryk for skifte."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det er ikke muligt at foretage nødopkald"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Vis ikke igen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Nødopkald kræver adgang til et mobilnetværk"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Underretninger"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderestilling af opkald"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Netværksunderretninger"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Tilgængeligt netværk"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Klokkeslæt og tidszoner"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Underretninger fra din it-administrator"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Underretninger"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo til udstilling i butik"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appen kører"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps, der bruger batteri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Forstørrelse"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Høreapparat"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Brug af hjælpefunktioner"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skærm"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nyt SIM-kort er indsat"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tryk for at konfigurere"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Din tidszone blev ændret"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Du er nu i <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Angiv tidspunkt"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Angiv dato"</string> <string name="date_time_set" msgid="4603445265164486816">"Angiv"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndstilstand"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dæmpet belysning"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ikke forbundet"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Forbundet"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Indlæser"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slip lydstyrkeknapperne. Du kan aktivere <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ved at holde begge lydstyrkeknapper nede igen i 3 sekunder."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 2 fingre, og slip derefter hurtigt."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 3 fingre, og slip derefter hurtigt."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørrelse"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vil du skifte til telefonens mikrofon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vil du skifte til mikrofonen i høreapparatet?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For at få bedre lyd, eller hvis dit høreapparat er ved at løbe tør for batteri. Der skiftes kun mikrofon under opkaldet."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan bruge mikrofonen i dit høreapparat til at foretage håndfrie opkald. Der skiftes kun mikrofon under opkaldet."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skift"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Indstillinger"</string> <string name="user_switched" msgid="7249833311585228097">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Skifter til <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> logges ud…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Af sikkerhedsmæssige årsager vises appindhold ikke ved skærmdeling"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Der blev automatisk oprettet forbindelse til satellit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og modtage beskeder uden et mobil- eller Wi-Fi-netværk"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Vil du bruge satellitbeskeder?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send og modtag beskeder uden et mobil- eller Wi-Fi-netværk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 6311880bb24a..5262da98d277 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilfunknetz nicht erreichbar"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Versuche, das bevorzugte Netzwerk zu ändern. Tippe, um ein anderes auszuwählen."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Notrufe nicht möglich"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Nicht noch einmal anzeigen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Für Notrufe ist ein Mobilfunknetz erforderlich"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Warnmeldungen"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Anrufweiterleitung"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Netzwerkwarnungen"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Netzwerk verfügbar"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-Status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Uhrzeit und Zeitzonen"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Benachrichtigungen zu wichtigen Updates von deinem IT-Administrator"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Warnmeldungen"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo für Einzelhandel"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App wird ausgeführt"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Strom verbrauchende Apps"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergrößerung"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hörgerät"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Nutzung der Bedienungshilfen"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> verbraucht Strom"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"App herunterladen"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Neue SIM-Karte eingelegt"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Zum Einrichten tippen"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Die Zeitzone hat sich geändert"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Du bist jetzt in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Uhrzeit festlegen"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum festlegen"</string> <string name="date_time_set" msgid="4603445265164486816">"Speichern"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhandmodus"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradunkel"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörgeräte"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nicht verbunden"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Verbunden"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Wird geladen"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lass die Lautstärketasten los. Halte zum Aktivieren von <xliff:g id="SERVICE_NAME">%1$s</xliff:g> beide Lautstärketasten noch einmal 3 Sekunden lang gedrückt."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 2 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 3 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergrößerung"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Zum Mikrofon des Smartphones wechseln?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Zum Mikrofon des Hörgeräts wechseln?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Zum Verbessern des Tons oder wenn der Akkustand des Hörgeräts niedrig ist. Das Mikrofon wird nur für die Dauer des Anrufs gewechselt."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kannst das Mikrofon deines Hörgeräts für Anrufe per Sprachbefehl verwenden. Das Mikrofon wird nur für die Dauer des Anrufs gewechselt."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Wechseln"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Einstellungen"</string> <string name="user_switched" msgid="7249833311585228097">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <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> wird abgemeldet…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aus Sicherheitsgründen werden bei der Bildschirmfreigabe App-Inhalte ausgeblendet"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Nachrichten per Satellit verwenden?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Du kannst ohne Mobilgerät oder WLAN Nachrichten senden und empfangen"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 23fc44ca9dcc..1d194f4e3b22 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Δεν είναι δυνατή η σύνδεση στο δίκτυο κινητής τηλεφωνίας"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Δοκιμάστε να αλλάξετε το προτιμώμενο δίκτυο. Πατήστε για αλλαγή."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Οι κλήσεις έκτακτης ανάγκης δεν είναι διαθέσιμες"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Να μην εμφανιστεί ξανά"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Για τις κλήσεις έκτακτης ανάγκης απαιτείται δίκτυο κινητής τηλεφωνίας"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ειδοποιήσεις"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Προώθηση κλήσης"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Ειδοποιήσεις δικτύου"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Το δίκτυο είναι διαθέσιμο"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Κατάσταση VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ώρα και ζώνες ώρας"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Ειδοποιήσεις από τον διαχειριστή IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Ειδοποιήσεις"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Επίδειξη λιανικής"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Η εφαρμογή εκτελείται"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Εφαρμογές που καταναλώνουν μπαταρία"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Μεγιστοποίηση"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Συσκευή ακοής"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Χρήση προσβασιμότητας"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Οθόνη"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί μπαταρία"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Λήψη εφαρμογής"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Τοποθετήθηκε νέα SIM"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Πατήστε για ρύθμιση"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Η ζώνη ώρας άλλαξε"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Βρίσκεστε πλέον στη ζώνη ώρας <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Ρύθμιση ώρας"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Ορισμός ημερομηνίας"</string> <string name="date_time_set" msgid="4603445265164486816">"Ορισμός"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Λειτουργία ενός χεριού"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Επιπλέον μείωση φωτεινότητας"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Συσκευές ακοής"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Αποσυνδέθηκε"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Συνδέθηκε"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Ενεργή"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Φόρτωση"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Αφήστε τα κουμπιά έντασης ήχου. Για να ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, πατήστε ξανά παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 2 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 3 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Μεγιστοποίηση"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Εναλλαγή στο μικρόφωνο του τηλεφώνου;"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Εναλλαγή στο μικρόφωνο του βοηθήματος ακοής;"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Για καλύτερο ήχο ή αν η μπαταρία του βοηθήματος ακοής είναι χαμηλή. Με αυτή την ενέργεια, το μικρόφωνό σας αλλάζει μόνο κατά τη διάρκεια της κλήσης."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Μπορείτε να χρησιμοποιήσετε το μικρόφωνο του βοηθήματος ακοής σας για κλήσεις handsfree. Με αυτή την ενέργεια, το μικρόφωνό σας αλλάζει μόνο κατά τη διάρκεια της κλήσης."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Εναλλαγή"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ρυθμίσεις"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Για λόγους ασφάλειας, έγινε απόκρυψη του περιεχομένου της εφαρμογής από την κοινή χρήση οθόνης"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Συνδέθηκε αυτόματα με δορυφόρο"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Μπορείτε να στέλνετε και να λαμβάνετε μηνύματα χωρίς δίκτυο κινητής τηλεφωνίας ή Wi-Fi."</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Χρήση της ανταλλαγής μηνυμάτων μέσω δορυφόρου;"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Αποστολή και λήψη μηνυμάτων χωρίς δίκτυο κινητής τηλεφωνίας ή Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Άνοιγμα Messages"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 823db75ca6f4..75432f8b59a6 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Do not show again"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Network alerts"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Network available"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Time and time zones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerts from your IT admin"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerts"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Retail demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hearing device"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"New SIM inserted"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tap to set it up"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Your time zone changed"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"You\'re now in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Set time"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Set date"</string> <string name="date_time_set" msgid="4603445265164486816">"Set"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Loading"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Use satellite messaging?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 83fd1186e006..fc4b8af6f0ba 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -302,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Network alerts"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Network available"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Time and time zones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerts from your IT admin"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerts"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Retail demo"</string> @@ -309,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hearing device"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string> @@ -1406,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"New SIM inserted"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tap to set it up"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Your time zone changed"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"You\'re now in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Set time"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Set date"</string> <string name="date_time_set" msgid="4603445265164486816">"Set"</string> @@ -1779,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-Handed mode"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Loading"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for 3 seconds."</string> @@ -1797,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2453,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"You can send and receive messages and use limited data by satellite"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Use satellite messaging?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 46a0d2b96869..7d642b71028d 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Do not show again"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Network alerts"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Network available"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Time and time zones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerts from your IT admin"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerts"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Retail demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hearing device"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"New SIM inserted"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tap to set it up"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Your time zone changed"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"You\'re now in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Set time"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Set date"</string> <string name="date_time_set" msgid="4603445265164486816">"Set"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Loading"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Use satellite messaging?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 22cf48f71439..dd8e69550fff 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Do not show again"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Network alerts"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Network available"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Time and time zones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerts from your IT admin"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerts"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Retail demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App running"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps consuming battery"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Magnification"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hearing device"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Accessibility usage"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using battery"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"New SIM inserted"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tap to set it up"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Your time zone changed"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"You\'re now in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Set time"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Set date"</string> <string name="date_time_set" msgid="4603445265164486816">"Set"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-handed mode"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnected"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connected"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Active"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Loading"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string> <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Logging out <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Use satellite messaging?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send and receive messages without a mobile or Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index b956286b7d2f..3451d58fe747 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede acceder a la red móvil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Presiona para cambiar la red preferida."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"No volver a mostrar"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Las llamadas de emergencia requieren una red móvil"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamada"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas de red"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Red disponible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Estado de VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora y zonas horarias"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas de tu administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo para punto de venta"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App en ejecución"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que consumen batería"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Dispositivos auditivos"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de accesibilidad"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Pantalla"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> está consumiendo batería"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Descargar app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nueva SIM insertada"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Presiona para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Se cambió tu zona horaria"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ahora estás en <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Configurar hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Configurar fecha"</string> <string name="date_time_set" msgid="4603445265164486816">"Establecer"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo de una mano"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Cargando"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vuelve a mantener presionadas las teclas de volumen durante 3 segundos."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"¿Quieres cambiar al micrófono del teléfono?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"¿Quieres cambiar al micrófono del audífono?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para conseguir un mejor sonido o si la batería de tu audífono está baja. Esto solo cambia el micrófono durante la llamada."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puedes usar el micrófono de tu audífono para realizar llamadas sin usar las manos. Esto solo cambia el micrófono durante la llamada."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuración"</string> <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Saliendo de <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Se ocultó el contenido de la app durante el uso compartido de la pantalla por motivos de seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática a satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes incluso si no tienes conexión a una red móvil o Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"¿Quieres usar la mensajería satelital?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía y recibe mensajes sin una red móvil ni Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index c50fbc7910ec..7b9dd4675800 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede establecer conexión con la red móvil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Toca para cambiar la red preferida."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"No volver a mostrar"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Para hacer llamadas de emergencia, necesitas conectarte a una red móvil"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamadas"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas de la red"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Red disponible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Estado de la VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora y zonas horarias"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas de tu administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo para tiendas"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicación en ejecución"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicaciones que consumen batería"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Audífono"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de accesibilidad"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Pantalla"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando la batería"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Descargar aplicación"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nueva SIM insertada"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toca para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Tu zona horaria ha cambiado"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Ahora estás en <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Establecer hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Establecer fecha"</string> <string name="date_time_set" msgid="4603445265164486816">"Establecer"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo Una mano"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audífonos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Cargando"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas las dos teclas de volumen de nuevo durante 3 segundos."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"¿Cambiar al micrófono del teléfono?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"¿Cambiar al micrófono del audífono?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para mejorar el sonido o si la batería de tu audífono está baja. Esta opción solo cambia el micrófono durante la llamada."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puedes usar el micrófono de tu audífono para hacer llamadas en manos libres. Esta opción solo cambia el micrófono durante la llamada."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ajustes"</string> <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Cerrando la sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"¿Usar mensajes por satélite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía y recibe mensajes sin una red móvil ni Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 3e3e5db60163..cf875408ed14 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobiilsidevõrguga ei saa ühendust"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Proovige eelistatud võrku vahetada. Puudutage muutmiseks."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hädaabikõned pole saadaval"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ära enam kuva"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Hädaabikõnede jaoks on vajalik mobiilsidevõrk"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Teatised"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Kõnede suunamine"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Võrguteavitused"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Võrk on saadaval"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-i olek"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Aeg ja ajavööndid"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Teie IT-administraatori teatised"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Teatised"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Poedemo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Rakendus töötab"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Rakendused kasutavad akutoidet"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Suurendus"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Kuuldeseade"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Juurdepääsetavuse kasutus"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekraan"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab akutoidet"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Laadi alla rakendus"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Uus SIM-kaart on sisestatud"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Puudutage seadistamiseks"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Teie ajavöönd muutus"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Olete praegu ajavööndis <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Kellaaja määramine"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Kuupäeva määramine"</string> <string name="date_time_set" msgid="4603445265164486816">"Määra"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ühekäerežiim"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Eriti tume"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuuldeseadmed"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ühendus katkestatud"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Ühendatud"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiivne"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Laadimine"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vabastage helitugevuse klahvid. Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisselülitamiseks vajutage uuesti mõlemat helitugevuse klahvi ja hoidke neid 3 sekundit all."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kahe sõrmega ekraani allservast üles ja vabastage kiiresti."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kolme sõrmega ekraani allservast üles ja vabastage kiiresti."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Kas vahetada telefoni mikrofonile?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Kas vahetada kuuldeaparaadi mikrofonile?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Parema heli tagamiseks või siis, kui tele kuuldeaparaadi aku on tühi. See vahetab teie mikrofoni ainult kõne ajal."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofon vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaheta"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Seaded"</string> <string name="user_switched" msgid="7249833311585228097">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Kasutaja <xliff:g id="NAME">%1$s</xliff:g> väljalogimine …"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamisel turvalisuse huvides peidetud"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Kas soovite kasutada satelliidipõhist sõnumsidet?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Sõnumite saatmine ja vastuvõtmine ilma mobiilside- või WiFi-võrguta"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 2f477f3b2010..8e689594ea2a 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ezin da konektatu sare mugikorrera"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Aldatu sare hobetsia. Sakatu aldatzeko."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ezin da egin larrialdi-deirik"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ez erakutsi berriro"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Sare mugikorrera konektatuta egon behar duzu larrialdi-deiak egin ahal izateko"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertak"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Dei-desbideratzea"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Sarearen alertak"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Sare bat erabilgarri dago"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN egoera"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ordua eta ordu-zonak"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IKT saileko administratzaileak bidalitako alertak"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertak"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Saltzaileentzako demoa"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikazio bat abian da"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Bateria kontsumitzen ari diren aplikazioak"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Lupa"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Entzumen-gailua"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Erabilerraztasun-hobespenak"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Pantaila"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ari da bateria erabiltzen"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Deskargatu aplikazioa"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM berria sartu da"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Sakatu konfiguratzeko"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Ordu-zonaz aldatu zara"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Oraingo ordu-zona: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Ezarri ordua"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Ezarri data"</string> <string name="date_time_set" msgid="4603445265164486816">"Ezarri"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Esku bakarreko modua"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Are ilunago"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Entzumen-gailuak"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Deskonektatuta"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Konektatuta"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktibo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Kargatzen"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Askatu bolumen-botoiak. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatzeko, eduki sakatuta berriro bi bolumen-botoiak hiru segundoz."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 2 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 3 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefonoaren mikrofonora aldatu nahi duzu?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Audifonoaren mikrofonora aldatu nahi duzu?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Audioaren kalitatea hobetzeko edo audifonoak bateria gutxi badu. Deirako soilik aldatzen da mikrofonoa."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Audifonoaren mikrofonoa erabil dezakezu esku libreko deiak egiteko. Deirako soilik aldatzen da mikrofonoa."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Aldatu"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ezarpenak"</string> <string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailearen saioa amaitzen…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aplikazioko edukia ezkutatu egin da pantaila partekatzeko eginbidetik, segurtasuna bermatzeko"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikoki konektatu da satelitera"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mezuak bidal eta jaso ditzakezu sare mugikorrik edo wifi-sarerik gabe"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Satelite bidezko mezularitza erabili nahi duzu?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Bidali eta jaso mezuak sare mugikorrik edo wifi-sarerik gabe"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index d8fdff631b7d..9f2c7bb43c69 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، تکضرب بزنید."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکانپذیر نیست"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"دیگر نشان داده نشود"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"برای برقراری تماس اضطراری به شبکه تلفن همراه نیاز دارید"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"بازارسال تماس"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"هشدارهای شبکه"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"شبکه دردسترس است"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"وضعیت VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"زمان و منطقههای زمانی"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"هشدارهایی از سرپرست فناوری اطلاعات"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"هشدارها"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"نمونه برای خردهفروشان"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"برنامه درحال اجرا"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"برنامههای مصرفکننده باتری"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"درشتنمایی"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"سمعک"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"کاربرد دسترسپذیری"</string> <string name="notification_channel_display" msgid="6905032605735615090">"نمایشگر"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحال استفاده کردن از باتری است"</string> @@ -1215,7 +1216,7 @@ <string name="editTextMenuTitle" msgid="857666911134482176">"کنشهای متنی"</string> <string name="error_handwriting_unsupported" msgid="7809438534946014050">"در این فیلد از دستنویسی پشتیبانی نمیشود"</string> <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"در فیلدهای گذرواژه از دستنویسی پشتیبانی نمیشود"</string> - <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"برگشت"</string> + <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"برگشتن"</string> <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"تغییر روش ورودی"</string> <string name="input_method_ime_switch_long_click_action_desc" msgid="3161942124116646998">"باز کردن انتخابگر روش ورودی"</string> <string name="input_method_switcher_settings_button" msgid="5609835654697108485">"تنظیمات"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"بارگیری برنامه"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"سیمکارت جدید جاگذاری شد"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"برای تنظیم آن تکضرب بزنید"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"منطقه زمانیتان تغییر کرد"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"درحالحاضر در <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) هستید"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"تنظیم زمان"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"تاریخ تنظیم"</string> <string name="date_time_set" msgid="4603445265164486816">"تنظیم"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"حالت یکدستی"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"بسیار کمنور"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"دستگاههای کمکشنوایی"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"متصل نیست"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"متصل"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"فعال"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"درحال بار کردن"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"کلیدهای میزان صدا را رها کنید. برای روشن کردن <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید میزان صدا را مجدداً بهمدت ۳ ثانیه فشار دهید و نگه دارید."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"دفعه بعد که از این میانبر استفاده کنید، این ویژگی باز میشود. با ۲ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"دفعه بعد که از این میانبر استفاده کنید، این ویژگی باز میشود. با ۳ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"درشتنمایی"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"از میکروفون تلفن استفاده شود؟"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"از میکروفون سمعک استفاده شود؟"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"برای صدای بهتر یا اگر شارژ باتری سمعک شما کم باشد. این کار فقط درطول تماس میکروفون شما را عوض میکند."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"برای تماس دستآزاد میتوانید از میکروفون سمعک خود استفاده کنید. این کار فقط درطول تماس میکروفون شما را عوض میکند."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"عوض کردن"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"تنظیمات"</string> <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> @@ -2029,7 +2034,7 @@ <string name="search_language_hint" msgid="7004225294308793583">"نام زبان را تایپ کنید"</string> <string name="language_picker_section_suggested" msgid="6556199184638990447">"پیشنهادی"</string> <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"پیشنهادی"</string> - <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"زبانهای پیشنهادی"</string> + <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"زبانهای پیشنهادشده"</string> <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"مناطق پیشنهادی"</string> <string name="language_picker_section_all" msgid="1985809075777564284">"همه زبانها"</string> <string name="region_picker_section_all" msgid="756441309928774155">"همه منطقهها"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"بهدلایل امنیتی، محتوای برنامه پساز همرسانی صفحهنمایش پنهان میشود"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"بهطور خودکار به ماهواره متصل شد"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"میتوانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"از «پیامرسانی ماهوارهای» استفاده شود؟"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ارسال و دریافت پیام بدون شبکه تلفن همراه یا Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیامنگار»"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 9f88732cd7b4..0b65ee2c5403 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobiiliverkkoon ei saada yhteyttä"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Kokeile vaihtaa ensisijaista verkkoa. Vaihda se napauttamalla."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hätäpuhelut eivät ole käytettävissä"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Älä näytä uudelleen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Hätäpuhelu edellyttää mobiiliverkkoa"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ilmoitukset"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Soitonsiirto"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Verkkoilmoitukset"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Verkko käytettävissä"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-tila"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Aika ja aikavyöhykkeet"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Ilmoitukset IT-järjestelmänvalvojalta"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Ilmoitukset"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Esittelytila"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Sovellus käynnissä"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Akkua kuluttavat sovellukset"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Suurennus"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Kuulolaite"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Esteetön käyttö"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Näyttö"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää akkua."</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Lataa sovellus"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Uusi SIM-kortti asetettu"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Määritä se napauttamalla"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Aikavyöhykkeesi on muuttunut"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Olet nyt aikavyöhykkeellä <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Aseta aika"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Aseta päivämäärä"</string> <string name="date_time_set" msgid="4603445265164486816">"Aseta"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Yhden käden moodi"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Erittäin himmeä"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuulolaitteet"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Yhteys katkaistu"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Yhdistetty"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiivinen"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Ladataan"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vapauta äänenvoimakkuuspainikkeet. Laita <xliff:g id="SERVICE_NAME">%1$s</xliff:g> päälle painamalla äänenvoimakkuuspainikkeita uudelleen kolmen sekunnin ajan."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kahdella sormella ja nosta sormet näytöltä nopeasti."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kolmella sormella ja nosta sormet näytöltä nopeasti."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurennus"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vaihdetaanko puhelimen mikrofoniin?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vaihdetaanko kuulolaitteen mikrofoniin?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Jos haluat paremman äänen tai kuulolaitteen akku on vähissä. Tämä vaihtaa mikrofonia vain puhelun ajaksi."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Voit soittaa ääniohjatusti kuulolaitteen mikrofonin avulla. Tämä vaihtaa mikrofonia vain puhelun ajaksi."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaihda"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Asetukset"</string> <string name="user_switched" msgid="7249833311585228097">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <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> kirjautuu ulos…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sovelluksen sisältö piilotettu näytön jakamiselta turvallisuussyistä"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Yhdistetty automaattisesti satelliittiin"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Voit lähettää ja vastaanottaa viestejä ilman mobiili‑ tai Wi-Fi-verkkoa"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Käytetäänkö satelliittiviestintää?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Lähetä ja vastaanota viestejä ilman mobiili- tai Wi-Fi-verkkoa"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index c535bc078b4d..e9331bb826c4 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible de joindre le réseau cellulaire"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer de réseau préféré. Touchez l\'écran pour changer."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Le service d\'appel d\'urgence n\'est pas accessible"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne plus afficher"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Les appels d\'urgence nécessitent un réseau cellulaire"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertes réseau"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Réseau accessible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"État du RPV"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Heure et fuseaux horaires"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertes de votre administrateur informatique"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertes"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Démo en magasin"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appli en cours d\'exécution"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applis qui sollicitent la pile"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Appareil auditif"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Usage des fonctionnalités d\'accessibilité"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Écran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'appli"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nouvelle carte SIM insérée"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Touchez ici pour effectuer la configuration"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vous avez changé de fuseau horaire"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Voici le fuseau horaire dans lequel vous vous trouvez maintenant : <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Définir l\'heure"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Définir la date"</string> <string name="date_time_set" msgid="4603445265164486816">"Paramètres"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode Une main"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Très sombre"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Déconnecté"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connecté"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Actif"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Chargement en cours…"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les touches de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, maintenez les deux touches de volume enfoncées pendant 3 secondes."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec deux doigts et relâchez rapidement."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec trois doigts et relâchez rapidement."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro pour la prothèse auditive?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour profiter d\'un meilleur son ou si la pile de votre prothèse auditive est faible. Cette option ne change votre micro que pendant l\'appel."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser votre microphone pour prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string> <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g> en cours..."</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué du Partage d\'écran par mesure de sécurité"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Utiliser la messagerie par satellite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envoyez et recevez des messages sans réseau cellulaire ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index aa45f91f0975..cbcc961f309a 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible d\'accéder au réseau mobile"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer le réseau préféré. Appuyez pour le modifier."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Appels d\'urgence non disponibles"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne plus afficher"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Les appels d\'urgence requièrent un réseau mobile"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertes réseau"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Réseau disponible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"État du VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Heure et fuseaux horaires"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertes de votre administrateur informatique"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertes"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Démonstration en magasin"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Application en cours d\'exécution"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applications utilisant la batterie"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Appareil auditif"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Utilisation de l\'accessibilité"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Écran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise la batterie"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'application"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nouvelle carte SIM insérée"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Appuyez ici pour effectuer la configuration."</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Votre fuseau horaire a changé"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Vous êtes maintenant sur le fuseau horaire <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Définir l\'heure"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Définir la date"</string> <string name="date_time_set" msgid="4603445265164486816">"Définir"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode une main"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminosité ultra-réduite"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Déconnecté"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connecté"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Actif"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Chargement"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec deux doigts et relâchez rapidement."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec trois doigts et relâchez rapidement."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro de l\'appareil auditif ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour améliorer le son ou si la batterie de votre appareil auditif est faible. Cette option change uniquement le micro pendant l\'appel."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option change uniquement le micro pendant l\'appel."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string> <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Déconnexion de <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran par mesure de sécurité"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Utiliser la messagerie par satellite ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envoyer et recevoir des messages sans réseau mobile ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index a1016b688282..25aac2cd0615 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Non se puido conectar coa rede de telefonía móbil"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Proba a cambiar a rede preferida. Toca para cambiar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"As chamadas de emerxencia non están dispoñibles"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Non mostrar de novo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emerxencia precisan unha rede de telefonía móbil"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de chamadas"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas de rede"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"A rede está dispoñible"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Estado da VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora e fusos horarios"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas do teu administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demostración comercial"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Estase executando a aplicación"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicacións que consomen batería"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliación"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Dispositivo auditivo"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de accesibilidade"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Pantalla"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo batería"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Descargar aplicación"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Introduciuse unha nova SIM"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tocar para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Cambiaches de fuso horario"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Estás en <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Configurar hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Establecer data"</string> <string name="date_time_set" msgid="4603445265164486816">"Configurar"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo dunha soa man"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Activo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Cargando"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solta as teclas de volume. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantenas premidas de novo durante 3 segundos."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A función abrirase cando volvas usar este atallo. Pasa dous dedos desde a parte inferior da pantalla e solta rapidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A función abrirase cando volvas usar este atallo. Pasa tres dedos desde a parte inferior da pantalla e solta rapidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Queres cambiar ao micrófono do teléfono?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Queres cambiar ao micrófono do audiófono?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para mellorar o son ou se o audiófono ten pouca batería. Esta acción só cambia o micrófono durante a chamada."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Podes usar o micrófono do audiófono para facer chamadas coas mans libres. Esta acción só cambia o micrófono durante a chamada."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambiar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configuración"</string> <string name="user_switched" msgid="7249833311585228097">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Pechando sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por seguranza, ocultouse o contido da aplicación na pantalla compartida"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Queres usar a mensaxaría por satélite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envía e recibe mensaxes sen ter acceso a redes de telefonía móbil ou wifi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index 046939b3bf3c..c38768dc3e30 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"મોબાઇલ નેટવર્ક સુધી પહોંચી શકાતું નથી"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"પસંદગીનું નેટવર્ક બદલવાનો પ્રયાસ કરો. બદલવા માટે ટૅપ કરો."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"કટોકટીની કૉલિંગ સેવા અનુપલબ્ધ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ફરી બતાવશો નહીં"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ઇમર્જન્સી કૉલ માટે મોબાઇલ નેટવર્કની આવશ્યકતા છે"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"અલર્ટ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"કૉલ ફૉર્વર્ડિંગ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"નેટવર્ક ચેતવણીઓ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"નેટવર્ક ઉપલબ્ધ છે"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN સ્થિતિ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"સમય અને સમય ઝોન"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"તમારા IT વ્યવસ્થાપક તરફથી અલર્ટ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"અલર્ટ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"રિટેલ ડેમો"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ઍપ ચાલી રહ્યું છે"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ઍપ બૅટરીનો વપરાશ કરી રહ્યાં છે"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"મોટું કરવાની સુવિધા"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"સાંભળવામાં મદદ આપતા ડિવાઇસ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ઍક્સેસિબિલિટી વપરાશ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ડિસ્પ્લે"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> બૅટરીનો ઉપયોગ કરી રહ્યું છે"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ઍપ ડાઉનલોડ કરો"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"નવું સિમ દાખલ કર્યું"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"તેને સેટ કરવા માટે ટૅપ કરો"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"તમારો સમય ઝોન બદલાયો છે"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"તમે <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)માં છો"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"સમય સેટ કરો"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"તારીખ સેટ કરો"</string> <string name="date_time_set" msgid="4603445265164486816">"સેટ કરો"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"એક-હાથે વાપરો મોડ"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"એક્સ્ટ્રા ડિમ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"સાંભળવામાં સહાય કરતા ડિવાઇસ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ડિસ્કનેક્ટેડ છે"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"કનેક્ટેડ છે"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"સક્રિય"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"લોડ કરી રહ્યાં છીએ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"વૉલ્યૂમ કી છોડી દો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ને ચાલુ કરવા માટે, 3 સેકન્ડ માટે બન્ને વૉલ્યૂમ કીને ફરીથી દબાવી રાખો."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 2 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 3 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"મોટું કરવું"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ફોનના માઇક પર સ્વિચ કરીએ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"સાંભળવામાં મદદ આપતા યંત્રના માઇક પર સ્વિચ કરીએ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"બહેતર સાઉન્ડ માટે અથવા જો સાંભળવામાં મદદ આપતા તમારા યંત્રની બૅટરી ઓછી હોય. કૉલ દરમિયાન આ ફક્ત તમારા માઇકને સ્વિચ કરે છે."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"તમે હાથના ઉપયોગ વિના કૉલ કરવા માટે સાંભળવામાં મદદ આપતા તમારા યંત્રના માઇક્રોફોનનો ઉપયોગ કરી શકો છો. કૉલ દરમિયાન આ ફક્ત તમારા માઇકને સ્વિચ કરે છે."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"સ્વિચ કરો"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"સેટિંગ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"સુરક્ષા માટે સ્ક્રીન શેર કરતી વખતે ઍપનું કન્ટેન્ટ છુપાવેલું છે"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"સેટેલાઇટ સાથે ઑટોમૅટિક રીતે કનેક્ટેડ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"તમે મોબાઇલ અથવા વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલી અને પ્રાપ્ત કરી શકો છો"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"શું સૅટલાઇટ મેસેજિંગનો ઉપયોગ કરીએ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"મોબાઇલ કે વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલો અને મેળવો"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 7717d0276916..6199c806d5e2 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क से कनेक्ट नहीं किया जा सका"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"पसंदीदा नेटवर्क बदलकर देखें. बदलने के लिए टैप करें."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपातकालीन कॉल करने की सुविधा उपलब्ध नहीं है"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"दोबारा न दिखाएं"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आपातकालीन कॉल के लिए मोबाइल नेटवर्क ज़रूरी है"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"सूचनाएं"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल को दूसरे नंबर पर भेजना"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"नेटवर्क संबंधी सूचनाएं"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"नेटवर्क उपलब्ध है"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN की स्थिति"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"टाइम और टाइम ज़ोन"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"आपके आईटी एडमिन से मिली चेतावनियां"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"सूचनाएं"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"खुदरा डेमो"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ऐप अभी इस्तेमाल हो रहा है"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"बैटरी की खपत करने वाले ऐप"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ज़ूम करने की सुविधा"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"कान की मशीन"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"सुलभता सुविधाओं का इस्तेमाल"</string> <string name="notification_channel_display" msgid="6905032605735615090">"डिसप्ले"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैटरी का इस्तेमाल कर रहा है"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ऐप्लिकेशन डाउनलोड करें"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"नई SIM डाली गई"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"इसे सेट करने के लिए टैप करें"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"आपका टाइम ज़ोन बदल गया है"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"अब आप <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) में हैं"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"समय सेट करें"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"तारीख सेट करें"</string> <string name="date_time_set" msgid="4603445265164486816">"सेट करें"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"वन-हैंडेड मोड"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"स्क्रीन की रोशनी को सामान्य लेवल से और कम करने की सुविधा"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"कान की मशीन"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिसकनेक्ट हो गया"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट हो गया"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"चालू है"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"लोड हो रहा है"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"आवाज़ बटन को छोड़ें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> की सुविधा चालू करने के लिए, आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर दो उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर तीन उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"क्या आपको फ़ोन के माइक्रोफ़ोन पर स्विच करना है?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"क्या आपको कान की मशीन के माइक पर स्विच करना है?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"बेहतर आवाज़ के लिए या कान की मशीन की बैटरी कम होने पर. यह सिर्फ़ कॉल के दौरान आपका माइक चालू करता है."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे, कॉल के दौरान सिर्फ़ आपका माइक चालू या बंद होता है."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करें"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग"</string> <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> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रीन शेयर करने के दौरान सुरक्षा के लिए, ऐप्लिकेशन का कॉन्टेंट छिपाया गया"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"सैटलाइट से अपने-आप कनेक्ट हो गया"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना भी मैसेज भेजे और पाए जा सकते हैं"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"सैटलाइट के ज़रिए मैसेज भेजें और पाएं. साथ ही, सीमित डेटा का इस्तेमाल करें"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"क्या आपको सैटलाइट की मदद से मैसेज भेजना है?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना मैसेज भेजें और पाएं"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 118b53928b61..5b3dc7c86658 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilna mreža nije dostupna"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite da biste je promijenili."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne prikazuj ponovo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za hitne pozive potrebna je mobilna mreža"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmjeravanje poziva"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Mrežna upozorenja"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Vrijeme i vremenske zone"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Upozorenja IT administratora"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozorenja"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Prodajni demo-način"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Izvodi se aplikacija"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije troše bateriju"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Povećavanje"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Slušno pomagalo"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Upotreba pristupačnosti"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Zaslon"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Preuzmite aplikaciju"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Umetnuta je nova SIM kartica"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dodirnite da biste je postavili"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vaša je vremenska zona promijenjena"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sada ste u vremenskoj zoni <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Postavljanje vremena"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Postavi datum"</string> <string name="date_time_set" msgid="4603445265164486816">"Postavi"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Način rada jednom rukom"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Još tamnije"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušna pomagala"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nije povezano"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Učitavanje"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite dvama prstima s dna zaslona."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite s dna zaslona trima prstima."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite li se prebaciti na mikrofon telefona?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite li se prebaciti na mikrofon slušnog pomagala?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za bolji zvuk ili ako je razina baterije slušnog pomagala niska. Time se mikrofon prebacuje samo tijekom poziva."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Time se mikrofon prebacuje samo tijekom poziva."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prebaci"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string> <string name="user_switched" msgid="7249833311585228097">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljivanje korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Sadržaj aplikacije sakriven je od dijeljenja zaslona radi sigurnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne mreže ili Wi-Fi mreže"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Želite li slati poruke putem satelita?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Šaljite i primajte poruke kad nije dostupna mobilna ili Wi-Fi mreža"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 09f162eba32e..117509955341 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"A mobilhálózat nem érhető el"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Próbálja meg módosítani a preferált hálózatot. Koppintson a módosításhoz."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Segélyhívás nem lehetséges"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne jelenjen meg újra"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"A segélyhíváshoz mobilhálózatra van szükség"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Értesítések"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Hívásátirányítás"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Hálózati értesítések"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Van elérhető hálózat"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-állapot"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Idő és időzónák"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Értesítések a rendszergazdától"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Értesítések"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Kiskereskedelmi bemutató"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Jelenleg futó alkalmazás"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Akkumulátort használó alkalmazások"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Nagyítás"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hallókészülék"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Kisegítő lehetőségek használata"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Kijelző"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás használja az akkumulátort"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Alkalmazás letöltése"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Új SIM behelyezve"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Koppintson rá a beállításhoz"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Az időzóna megváltozott"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Mostani időzóna: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Idő beállítása"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Dátum beállítása"</string> <string name="date_time_set" msgid="4603445265164486816">"Beállítás"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Egykezes mód"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extrasötét"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hallásjavító eszközök"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Leválasztva"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Csatlakozva"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktív"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Betöltés"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Engedje fel a hangerőszabályzó gombokat. A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolásához tartsa újra lenyomva a hangerőszabályzó gombokat három másodpercig."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé két ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé három ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Nagyítás"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Átvált a telefon mikrofonjára?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Átvált a hallókészülék mikrofonjára?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"A jobb hangzás érdekében, vagy ha a hallókészülék akkumulátora merülőben van. Csak a mikrofont kapcsolja át hívás közben."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Használhatja hallókészüléke mikrofonját a szabadkezes hívásokhoz. Csak a mikrofont kapcsolja át hívás közben."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Váltás"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Beállítások"</string> <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string> <string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <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> kijelentkeztetése folyamatban van…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Apptartalom elrejtve a megosztástól a biztonság érdekében"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Műholdas üzenetváltást szeretne használni?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 7a821a695edc..c89544823314 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Չհաջողվեց միանալ բջջային ցանցին"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Փորձեք այլ ցանցի միանալ: Հպեք՝ նախընտրած ցանցը փոխելու համար:"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Շտապ կանչերը հասանելի չեն"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Այլևս ցույց չտալ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Շտապ կանչերի համար բջջային ցանց է անհրաժեշտ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ծանուցումներ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Զանգի վերահասցեավորում"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Ցանցային զգուշացումներ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Ցանցը հասանելի է"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN կարգավիճակ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ժամ և ժամային գոտի"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Ծանուցումներ ձեր ՏՏ ադմինիստրատորից"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Ծանուցումներ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Խանութի ցուցադրական ռեժիմ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Հավելվածն աշխատում է"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Մարտկոցի լիցքը ծախսող հավելվածներ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Խոշորացում"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Լսողական սարք"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Հատուկ գործառույթների օգտագործում"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Էկրան"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"«<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածը ծախսում է մարտկոցի լիցքը"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Ներբեռնել հավելվածը"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Տեղադրվել է նոր SIM քարտ"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Հպեք՝ կարգավորելու համար"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Ձեր ժամային գոտին փոխվեց"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Դուք այժմ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ժամային գոտում եք"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Սահմանել ժամը"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Սահմանել ամսաթիվը"</string> <string name="date_time_set" msgid="4603445265164486816">"Սահմանել"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Մեկ ձեռքի ռեժիմ"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Հավելյալ խամրեցում"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Լսողական սարքեր"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Անջատված է"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Միացված է"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Ակտիվ է"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Բեռնում"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Բաց թողեք ձայնի ուժգնության կոճակները։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացնելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակը։"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երկու մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երեք մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Խոշորացում"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Անցնե՞լ հեռախոսի խոսափողին"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Անցնե՞լ լսողական սարքի խոսափողին"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Խոսափողը կարող եք օգտագործել, եթե ձայնի որակը ցածր է, կամ լսողական սարքի մարտկոցի լիցքը քիչ է։ Դուք կանցնեք խոսափողին միայն զանգի ընթացքում։"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Լսողական սարքի խոսափողը կարող եք օգտագործել ձայնային կառավարման համար։ Դուք կանցնեք խոսափողին միայն զանգի ընթացքում։"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Անցնել"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Կարգավորումներ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներով՝ բովանդակությունը թաքցվել է ցուցադրումից"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Ավտոմատ միացել է արբանյակին"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք հաղորդագրություններ ուղարկել և ստանալ առանց բջջային կամ Wi-Fi կապի"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Օգտագործե՞լ արբանյակային հաղորդագրումը"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Ուղարկեք և ստացեք հաղորդագրություններ առանց բջջային կամ Wi-Fi ցանցի"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 3c0deb7c62ce..26a79e0b53a9 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat menjangkau jaringan seluler"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Coba ubah jaringan pilihan. Ketuk untuk mengubah."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan darurat tidak tersedia"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Jangan Tampilkan Lagi"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Panggilan darurat memerlukan jaringan seluler"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Notifikasi"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Penerusan panggilan"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Notifikasi jaringan"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Jaringan tersedia"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Waktu dan zona waktu"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Notifikasi dari admin IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Notifikasi"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo promo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikasi berjalan"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikasi yang menggunakan baterai"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pembesaran"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Alat bantu dengar"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Penggunaan aksesibilitas"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Layar"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan baterai"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Download aplikasi"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM baru dimasukkan"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Ketuk untuk menyiapkan"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Zona waktu Anda diubah"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Anda sekarang berada di <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Setel waktu"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Setel tanggal"</string> <string name="date_time_set" msgid="4603445265164486816">"Setel"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mode satu tangan"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra redup"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Alat bantu dengar"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Tidak terhubung"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Terhubung"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktif"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Memuat"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan kedua tombol volume lagi selama 3 detik."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 2 jari dari bawah layar, lalu lepaskan dengan cepat."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 3 jari dari bawah layar, lalu lepaskan dengan cepat."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Beralih ke mikrofon ponsel?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Beralih ke mikrofon alat bantu dengar?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Untuk mendapatkan kualitas suara yang lebih baik atau jika daya baterai alat bantu dengar Anda lemah. Tindakan ini hanya akan mengalihkan mikrofon Anda selama panggilan."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Anda dapat menggunakan mikrofon alat bantu dengar untuk melakukan panggilan handsfree. Tindakan ini hanya akan mengalihkan mikrofon Anda selama panggilan."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Alihkan"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Setelan"</string> <string name="user_switched" msgid="7249833311585228097">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Mengeluarkan <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar karena alasan keamanan"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Gunakan fitur pesan satelit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 6a3519134688..f6d043b170ed 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ekki næst samband við farsímakerfi"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prófaðu að velja annað símkerfi. Ýttu til að breyta."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Neyðarsímtöl eru ekki í boði"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ekki birta aftur"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Neyðarsímtöl krefjast farsímakerfis"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Tilkynningar"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Símtalsflutningur"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Viðvaranir netkerfis"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Net í boði"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Staða VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Tími og tímabelti"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Tilkynningar frá kerfisstjóra"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Tilkynningar"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Kynningarútgáfa fyrir verslanir"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Forrit er í gangi"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Forrit sem nota rafhlöðuorku"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Stækkun"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Heyrnartæki"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Aðgengisnotkun"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skjár"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> notar rafhlöðuorku"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Sækja forritið"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nýtt SIM-kort sett í"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Ýttu til að setja það upp"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Tímabeltinu þínu var breytt"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Þú ert nú á <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Veldu tíma"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Veldu dagsetningu"</string> <string name="date_time_set" msgid="4603445265164486816">"Velja"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Einhent stilling"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mjög dökkt"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Heyrnartæki"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Aftengt"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Tengt"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Virkt"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Hleður"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slepptu hljóðstyrkstökkunum. Til að kveikja á <xliff:g id="SERVICE_NAME">%1$s</xliff:g> skaltu halda báðum hljóðstyrkstökkunum aftur inni í 3 sekúndur."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 2 fingrum frá neðsta hluta skjásins og slepptu hratt."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 3 fingrum frá neðsta hluta skjásins og slepptu hratt."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Skipta yfir í hljóðnema símans?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Skipta yfir í hljóðnema heyrnartækis?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Fyrir betri hljómgæði eða ef lítil hleðsla er á heyrnartækinu. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skipta"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Stillingar"</string> <string name="user_switched" msgid="7249833311585228097">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Skráir <xliff:g id="NAME">%1$s</xliff:g> út…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Efni forrits falið í skjádeilingu af öryggisástæðum"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Tengdist sjálfkrafa við gervihnött"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Þú getur sent og móttekið skilaboð án tengingar við farsímakerfi eða Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Nota skilaboð í gegnum gervihnött?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Senda og fá skilaboð án tengingar við farsímakerfi eða Wi-Fi-net"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index db402c50205b..96075003f0b2 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossibile raggiungere la rete mobile"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova a cambiare la rete preferita. Tocca per cambiare."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chiamate di emergenza non disponibili"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Non mostrare più"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per le chiamate di emergenza è necessaria una rete mobile"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Avvisi"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Deviazione chiamate"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Avvisi di rete"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rete disponibile"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stato della VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ora e fusi orari"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Avvisi dall\'amministratore IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Avvisi"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo retail"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App in esecuzione"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"App che consumano la batteria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ingrandimento"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Protesi uditiva"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Utilizzo dell\'accessibilità"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> sta consumando la batteria"</string> @@ -694,7 +695,7 @@ <string name="fingerprint_error_security_update_required" msgid="8440349108169661934">"Sensore temporaneamente disattivato"</string> <string name="fingerprint_error_bad_calibration" msgid="6770614925736183528">"Impossibile usare il sensore di impronte digitali. Contatta un fornitore di servizi di riparazione."</string> <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Tasto di accensione premuto"</string> - <string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string> + <string name="fingerprint_name_template" msgid="8941662088160289778">"Impronta <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Usa l\'impronta"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usa l\'impronta o il blocco schermo"</string> <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Scarica app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nuova SIM inserita"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tocca per configurarla"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Il tuo fuso orario è cambiato"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Il tuo fuso orario attuale è <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Imposta ora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Imposta data"</string> <string name="date_time_set" msgid="4603445265164486816">"Imposta"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modalità a una mano"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Protesi uditive"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Disconnesso"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Connesso"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Attivo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Caricamento in corso…"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 2 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 3 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passare al microfono dello smartphone?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passare al microfono dell\'apparecchio acustico?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per una migliore resa audio o se la batteria dell\'apparecchio acustico è scarica. In questo modo, il microfono viene attivato solo durante la chiamata."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. In questo modo, il microfono viene attivato solo durante la chiamata."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambia"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Impostazioni"</string> <string name="user_switched" msgid="7249833311585228097">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Disconnessione di <xliff:g id="NAME">%1$s</xliff:g> in corso…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenuti dell\'app nascosti dalla condivisione schermo per sicurezza"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Connessione automatica al satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puoi inviare e ricevere messaggi senza una rete mobile o Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Utilizzare i messaggi via satellite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Invia e ricevi messaggi senza una rete mobile o Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 503eb9747c96..d25cf01602e4 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -86,10 +86,9 @@ <string name="RestrictedStateContent" msgid="7693575344608618926">"הושבת באופן זמני על ידי הספק"</string> <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"השירות הושבת באופן זמני על ידי הספק עבור SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string> <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"לא ניתן להתחבר לרשת הסלולרית"</string> - <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"אפשר לנסות לשנות את הרשת המועדפת. יש להקיש כדי לשנות אותה."</string> + <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"אפשר לנסות לשנות את הרשת המועדפת. יש ללחוץ כדי לשנות אותה."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"שיחות חירום לא זמינות"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"לא להציג את זה שוב"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"כדי לבצע שיחות חירום, צריך להתחבר לרשת סלולרית"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"התראות"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"העברת שיחות"</string> @@ -210,7 +209,7 @@ <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"המרחב הפרטי הוסר"</string> <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"הארגון שלך לא מאפשר שימוש במרחבים פרטיים במכשיר המנוהל הזה."</string> <string name="network_logging_notification_title" msgid="554983187553845004">"המכשיר מנוהל"</string> - <string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל את המכשיר הזה והוא עשוי לנטר את התנועה ברשת. יש להקיש לקבלת פרטים."</string> + <string name="network_logging_notification_text" msgid="1327373071132562512">"הארגון שלך מנהל את המכשיר הזה והוא עשוי לנטר את התנועה ברשת. יש ללחוץ לקבלת פרטים."</string> <string name="location_changed_notification_title" msgid="3620158742816699316">"לאפליקציות יש הרשאת גישה למיקום שלך"</string> <string name="location_changed_notification_text" msgid="7158423339982706912">"יש לפנות למנהל ה-IT כדי לקבל מידע נוסף"</string> <string name="geofencing_service" msgid="3826902410740315456">"שירות להגדרת גבולות וירטואליים"</string> @@ -304,6 +303,8 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"התראות רשת"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"יש רשת זמינה"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"סטטוס ה-VPN"</string> + <!-- no translation found for notification_channel_system_time (1660313368058030441) --> + <skip /> <string name="notification_channel_device_admin" msgid="6384932669406095506">"התראות ממנהל ה-IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"התראות"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"הדגמה לקמעונאים"</string> @@ -311,11 +312,13 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"אפליקציה פועלת"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"אפליקציות שמרוקנות את הסוללה"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"הגדלה"</string> + <!-- no translation found for notification_channel_accessibility_hearing_device (7816963856388758952) --> + <skip /> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"שימוש בנגישות"</string> <string name="notification_channel_display" msgid="6905032605735615090">"מסך"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בסוללה"</string> <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות משתמשות בסוללה"</string> - <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"אפשר להקיש כדי לקבל פרטים על צריכה של נתונים וסוללה"</string> + <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"אפשר ללחוץ כדי לקבל פרטים על צריכה של נתונים וסוללה"</string> <string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>, <xliff:g id="LEFT_SIDE">%1$s</xliff:g>"</string> <string name="safeMode" msgid="8974401416068943888">"מצב בטוח"</string> <string name="android_system_label" msgid="5974767339591067210">"מערכת Android"</string> @@ -356,13 +359,13 @@ <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"אחזור תוכן של חלון"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"בדיקת התוכן של חלון שאיתו מתבצעת אינטראקציה."</string> <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"הפעלה של \'גילוי באמצעות מגע\'"</string> - <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"פריטים שמקישים עליהם יוקראו בקול, וניתן לנווט במסך באמצעות תנועות."</string> + <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"פריטים שלוחצים עליהם יוקראו בקול, וניתן לנווט במסך באמצעות תנועות."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"הצגת טקסט בזמן הקלדה"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"כולל נתונים אישיים כמו מספרי כרטיס אשראי וסיסמאות."</string> <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"שליטה בהגדלת התצוגה"</string> <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"קביעת המרחק מהתצוגה ומיקום התצוגה."</string> <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"ביצוע תנועות"</string> - <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"יכול להקיש, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string> + <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"יכול ללחוץ, להחליק, לעשות תנועת צביטה ולבצע תנועות אחרות."</string> <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"תנועות של טביעות אצבעות"</string> <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"אפשרות לזהות תנועות בזמן נגיעה בחיישן טביעות האצבע של המכשיר."</string> <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"צילום המסך"</string> @@ -693,7 +696,7 @@ <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"במכשיר הזה אין חיישן טביעות אצבע"</string> <string name="fingerprint_error_security_update_required" msgid="8440349108169661934">"החיישן מושבת באופן זמני"</string> <string name="fingerprint_error_bad_calibration" msgid="6770614925736183528">"לא ניתן להשתמש בחיישן טביעות האצבע. צריך ליצור קשר עם ספק תיקונים."</string> - <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"לחצן ההפעלה נלחץ"</string> + <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"כפתור ההפעלה נלחץ"</string> <string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string> <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"שימוש בטביעת אצבע"</string> <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"שימוש בטביעת אצבע או בנעילת מסך"</string> @@ -709,7 +712,7 @@ <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"אפשר להשתמש בביטול הנעילה בטביעת אצבע כשהפנים שלך לא מזוהות, למשל כשאין מספיק אור"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"פתיחה בזיהוי פנים"</string> <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"בעיה בפתיחה ע\"י זיהוי הפנים"</string> - <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"יש להקיש כדי למחוק את התבנית לזיהוי הפנים, ואז להוסיף תבנית חדשה לזיהוי הפנים"</string> + <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"יש ללחוץ כדי למחוק את התבנית לזיהוי הפנים, ואז להוסיף תבנית חדשה לזיהוי הפנים"</string> <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"כדי להשתמש בתכונה \'פתיחה ע\"י זיהוי הפנים\', יש להפעיל את ה"<b>"גישה למצלמה"</b>" בהגדרות > פרטיות"</string> <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"פתיחה בטביעת אצבע"</string> <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"לא ניתן להשתמש בחיישן טביעות האצבע"</string> @@ -994,7 +997,7 @@ <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"יש להקליד את קוד ה-PUK ואת קוד האימות החדש"</string> <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"קוד PUK"</string> <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"קוד אימות חדש"</string> - <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"יש להקיש כדי להקליד את הסיסמה"</font></string> + <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"יש ללחוץ כדי להקליד את הסיסמה"</font></string> <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"יש להקליד סיסמה לביטול הנעילה"</string> <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"יש להקליד קוד אימות לביטול הנעילה"</string> <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"קוד אימות שגוי"</string> @@ -1106,7 +1109,7 @@ <string name="js_dialog_before_unload_negative_button" msgid="3873765747622415310">"להישאר בדף הזה"</string> <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nבטוח שברצונך לנווט אל מחוץ לדף הזה?"</string> <string name="autofill_window_title" msgid="4379134104008111961">"מילוי אוטומטי באמצעות <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string> - <string name="permlab_setAlarm" msgid="1158001610254173567">"הגדרת התראה"</string> + <string name="permlab_setAlarm" msgid="1158001610254173567">"הגדרת שעון מעורר"</string> <string name="permdesc_setAlarm" msgid="2185033720060109640">"מאפשרת לאפליקציה להגדיר התראה באפליקציה מותקנת של שעון מעורר. אפליקציות מסוימות של שעון מעורר אינן מיישמות את התכונה הזו."</string> <string name="permlab_addVoicemail" msgid="4770245808840814471">"הוספה של דואר קולי"</string> <string name="permdesc_addVoicemail" msgid="5470312139820074324">"מאפשרת לאפליקציה להוסיף הודעות לתיבת הדואר הקולי."</string> @@ -1224,7 +1227,7 @@ <string name="low_internal_storage_view_text" msgid="8172166728369697835">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string> <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"אין מספיק מקום אחסון עבור המערכת. עליך לוודא שיש לך מקום פנוי בנפח של 250MB ולהתחיל שוב."</string> <string name="app_running_notification_title" msgid="8985999749231486569">"אפליקציית <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת"</string> - <string name="app_running_notification_text" msgid="5120815883400228566">"יש להקיש לקבלת מידע נוסף או כדי לעצור את האפליקציה."</string> + <string name="app_running_notification_text" msgid="5120815883400228566">"יש ללחוץ לקבלת מידע נוסף או כדי לעצור את האפליקציה."</string> <string name="ok" msgid="2646370155170753815">"אישור"</string> <string name="cancel" msgid="6908697720451760115">"ביטול"</string> <string name="yes" msgid="9069828999585032361">"אישור"</string> @@ -1315,15 +1318,15 @@ <string name="android_preparing_apk" msgid="589736917792300956">"המערכת מכינה את <xliff:g id="APPNAME">%1$s</xliff:g>."</string> <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"מתבצעת הפעלה של אפליקציות."</string> <string name="android_upgrading_complete" msgid="409800058018374746">"תהליך האתחול בשלבי סיום."</string> - <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות במהלך ההגדרה של טביעת האצבע שלך."</string> + <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"לחצת על כפתור ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות ללחוץ בעדינות במהלך ההגדרה של טביעת האצבע שלך."</string> <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"לסיום ההגדרה, יש לכבות את המסך"</string> <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"כיבוי"</string> <string name="fp_power_button_bp_title" msgid="5585506104526820067">"להמשיך לאמת את טביעת האצבע שלך?"</string> - <string name="fp_power_button_bp_message" msgid="2983163038168903393">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות כדי לאמת את טביעת האצבע שלך."</string> + <string name="fp_power_button_bp_message" msgid="2983163038168903393">"לחצת על כפתור ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות ללחוץ בעדינות כדי לאמת את טביעת האצבע שלך."</string> <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"כיבוי המסך"</string> <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"המשך"</string> <string name="heavy_weight_notification" msgid="8382784283600329576">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת"</string> - <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"יש להקיש כדי לחזור למשחק"</string> + <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"יש ללחוץ כדי לחזור למשחק"</string> <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"בחירת משחק"</string> <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"לקבלת ביצועים טובים יותר, רק אחד מבין המשחקים האלה יכול להיות פתוח בכל פעם."</string> <string name="old_app_action" msgid="725331621042848590">"חזרה אל <xliff:g id="OLD_APP">%1$s</xliff:g>"</string> @@ -1331,7 +1334,7 @@ <string name="new_app_description" msgid="1958903080400806644">"אפליקציית <xliff:g id="OLD_APP">%1$s</xliff:g> תיסגר ללא שמירה"</string> <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> חורג ממגבלת הזיכרון"</string> <string name="dump_heap_ready_notification" msgid="2302452262927390268">"תמונת מצב של הזיכרון מוכנה עבור <xliff:g id="PROC">%1$s</xliff:g>"</string> - <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Dump של ערימה נאסף. יש להקיש כדי לשתף."</string> + <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Dump של ערימה נאסף. יש ללחוץ כדי לשתף."</string> <string name="dump_heap_title" msgid="4367128917229233901">"לשתף את תמונת המצב של הזיכרון?"</string> <string name="dump_heap_text" msgid="1692649033835719336">"התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת הזיכרון בגודל <xliff:g id="SIZE">%2$s</xliff:g>. תמונת מצב של הזיכרון זמינה לשיתוף עם המפתח. חשוב לנקוט זהירות: תמונת המצב של הזיכרון עשויה לכלול מידע אישי שאליו יש לאפליקציה גישה."</string> <string name="dump_heap_system_text" msgid="6805155514925350849">"התהליך <xliff:g id="PROC">%1$s</xliff:g> חרג ממגבלת הזיכרון בגודל <xliff:g id="SIZE">%2$s</xliff:g>. יש Dump של ערימה זמין לשיתוף. חשוב לנקוט זהירות: ה-Dump של הערימה עשוי לכלול מידע אישי רגיש שאליו יש לתהליך גישה. ייתכן שמידע זה כולל נתונים שהקלדת."</string> @@ -1363,12 +1366,12 @@ <!-- 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> <string name="network_partial_connectivity" msgid="4791024923851432291">"הקישוריות של <xliff:g id="NETWORK_SSID">%1$s</xliff:g> מוגבלת"</string> - <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"יש להקיש כדי להתחבר בכל זאת"</string> + <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"יש ללחוץ כדי להתחבר בכל זאת"</string> <string name="network_switch_metered" msgid="1531869544142283384">"מעבר אל <xliff:g id="NETWORK_TYPE">%1$s</xliff:g>"</string> <string name="network_switch_metered_detail" msgid="1358296010128405906">"המכשיר משתמש ברשת <xliff:g id="NEW_NETWORK">%1$s</xliff:g> כשלרשת <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> אין גישה לאינטרנט. עשויים לחול חיובים."</string> <string name="network_switch_metered_toast" msgid="501662047275723743">"בוצע מעבר מרשת <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> לרשת <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string> @@ -1407,7 +1410,11 @@ <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"אפשר להוריד את האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> כדי להפעיל את כרטיס ה-SIM החדש"</string> <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"להורדת האפליקציה"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ה-SIM החדש הוכנס"</string> - <string name="carrier_app_notification_text" msgid="6567057546341958637">"יש להקיש כדי להגדיר"</string> + <string name="carrier_app_notification_text" msgid="6567057546341958637">"יש ללחוץ כדי להגדיר"</string> + <!-- no translation found for time_zone_change_notification_title (5232503069219193218) --> + <skip /> + <!-- no translation found for time_zone_change_notification_body (6135793674904665585) --> + <skip /> <string name="time_picker_dialog_title" msgid="9053376764985220821">"הגדרת שעה"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"הגדרת תאריך"</string> <string name="date_time_set" msgid="4603445265164486816">"הגדרה"</string> @@ -1425,15 +1432,15 @@ <string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI באמצעות USB מופעל"</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_power_notification_message" msgid="7284765627437897702">"המכשיר המחובר בטעינה. יש להקיש לאפשרויות נוספות."</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> + <string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש ללחוץ לקבלת מידע נוסף."</string> <string name="adb_active_notification_title" msgid="408390247354560331">"ניפוי באגים ב-USB מחובר"</string> - <string name="adb_active_notification_message" msgid="5617264033476778211">"צריך להקיש כדי להשבית את ניפוי הבאגים ב-USB"</string> + <string name="adb_active_notification_message" msgid="5617264033476778211">"צריך ללחוץ כדי להשבית את ניפוי הבאגים ב-USB"</string> <string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"יש ללחוץ על ההתראה כדי להשבית ניפוי באגים ב-USB."</string> <string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ניפוי הבאגים האלחוטי מחובר"</string> - <string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש להקיש כדי להשבית ניפוי באגים אלחוטי"</string> + <string name="adbwifi_active_notification_message" msgid="930987922852867972">"יש ללחוץ כדי להשבית ניפוי באגים אלחוטי"</string> <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string> <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"מצב מסגרת בדיקה הופעל"</string> <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב \'מסגרת בדיקה\' צריך לאפס להגדרות היצרן."</string> @@ -1444,7 +1451,7 @@ <string name="mte_override_notification_title" msgid="4731115381962792944">"ה-MTE הניסיוני הופעל"</string> <string name="mte_override_notification_message" msgid="2441170442725738942">"יכולה להיות השפעה על הביצועים והיציבות. יש להפעיל מחדש כדי להשבית. אם ההפעלה מתבצעת באמצעות arm64.memtag.bootctl, צריך להגדיר מראש לערך none."</string> <string name="usb_contaminant_detected_title" msgid="4359048603069159678">"יש נוזלים או חלקיקים ביציאת ה-USB"</string> - <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string> + <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"יציאת ה-USB הושבתה באופן אוטומטי. יש ללחוץ לקבלת מידע נוסף."</string> <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"ניתן להשתמש ביציאת ה-USB"</string> <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"הטלפון לא מזהה יותר נוזלים וחלקיקים."</string> <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"עיבוד דוח על באג..."</string> @@ -1459,32 +1466,32 @@ <string name="hardware" msgid="3611039921284836033">"שימוש במקלדת שמופיעה במסך"</string> <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"הגדרה של <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string> <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"הגדרת מקלדות פיזיות"</string> - <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"יש להקיש כדי לבחור שפה ופריסה"</string> + <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"יש ללחוץ כדי לבחור שפה ופריסה"</string> <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"הצגה מעל אפליקציות אחרות"</string> <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"תצוגה של <xliff:g id="NAME">%s</xliff:g> מעל אפליקציות אחרות"</string> <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> מוצגת מעל אפליקציות אחרות"</string> - <string name="alert_windows_notification_message" msgid="6538171456970725333">"אם אינך רוצה שהאפליקציה <xliff:g id="NAME">%s</xliff:g> תשתמש בתכונה הזו, אפשר להקיש כדי לפתוח את ההגדרות ולהשבית אותה."</string> + <string name="alert_windows_notification_message" msgid="6538171456970725333">"אם אינך רוצה שהאפליקציה <xliff:g id="NAME">%s</xliff:g> תשתמש בתכונה הזו, אפשר ללחוץ כדי לפתוח את ההגדרות ולהשבית אותה."</string> <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"כיבוי"</string> <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"בתהליך בדיקה של <xliff:g id="NAME">%s</xliff:g>…"</string> <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"מתבצעת בדיקה של התוכן הנוכחי"</string> <string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"אחסון המדיה בתהליך ניתוח"</string> <string name="ext_media_new_notification_title" msgid="3517407571407687677">"<xliff:g id="NAME">%s</xliff:g> חדש"</string> <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string> - <string name="ext_media_new_notification_message" msgid="6095403121990786986">"צריך להקיש כדי להגדיר"</string> + <string name="ext_media_new_notification_message" msgid="6095403121990786986">"צריך ללחוץ כדי להגדיר"</string> <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"יש לבחור כדי להגדיר"</string> - <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש להקיש כדי להוציא את המדיה."</string> + <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש ללחוץ כדי להוציא את המדיה."</string> <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"לאחסון של תמונות, סרטונים, מוזיקה ועוד"</string> <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"עיון בקובצי המדיה"</string> <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"בעיה עם <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string> - <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"יש להקיש כדי לפתור את הבעיה"</string> + <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"יש ללחוץ כדי לפתור את הבעיה"</string> <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> פגום. יש ללחוץ כדי לפתור את הבעיה."</string> - <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש להקיש כדי להוציא את המדיה."</string> + <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר. יש ללחוץ כדי להוציא את המדיה."</string> <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"בוצע זיהוי של <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"המדיה <xliff:g id="NAME">%s</xliff:g> לא פועלת"</string> - <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"יש להקיש כדי להגדיר"</string> + <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"יש ללחוץ כדי להגדיר"</string> <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"יש לבחור כדי להגדיר את <xliff:g id="NAME">%s</xliff:g> בפורמט נתמך."</string> <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"ייתכן שיהיה צורך לפרמט מחדש את המכשיר"</string> <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> הוסר באופן בלתי צפוי"</string> @@ -1529,7 +1536,7 @@ <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"מאפשרת לאפליקציה לבקש רשות להתעלם מאופטימיזציות של הסוללה לאפליקציה הזו."</string> <string name="permlab_queryAllPackages" msgid="2928450604653281650">"שליחת שאילתות לכל החבילות"</string> <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"מאפשרת לאפליקציה לראות את כל החבילות המותקנות."</string> - <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"יש להקיש פעמיים לשינוי המרחק מהתצוגה"</string> + <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"יש ללחוץ פעמיים לשינוי המרחק מהתצוגה"</string> <string name="gadget_host_error_inflating" msgid="2449961590495198720">"לא ניתן להוסיף widget."</string> <string name="ime_action_go" msgid="5536744546326495436">"התחלה"</string> <string name="ime_action_search" msgid="4501435960587287668">"חיפוש"</string> @@ -1561,8 +1568,8 @@ <string name="notification_ranker_binding_label" msgid="432708245635563763">"שירות של דירוג התראות"</string> <string name="vpn_title" msgid="5906991595291514182">"VPN מופעל"</string> <string name="vpn_title_long" msgid="6834144390504619998">"VPN מופעל על ידי <xliff:g id="APP">%s</xliff:g>"</string> - <string name="vpn_text" msgid="2275388920267251078">"יש להקיש כדי לנהל את הרשת."</string> - <string name="vpn_text_long" msgid="278540576806169831">"בוצע חיבור אל <xliff:g id="SESSION">%s</xliff:g>. יש להקיש כדי לנהל את הרשת."</string> + <string name="vpn_text" msgid="2275388920267251078">"יש ללחוץ כדי לנהל את הרשת."</string> + <string name="vpn_text_long" msgid="278540576806169831">"בוצע חיבור אל <xliff:g id="SESSION">%s</xliff:g>. יש ללחוץ כדי לנהל את הרשת."</string> <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"ה-VPN שמופעל תמיד, מתחבר..."</string> <string name="vpn_lockdown_connected" msgid="2853127976590658469">"ה-VPN שפועל תמיד, מחובר"</string> <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"אין חיבור ל-VPN שפועל כל הזמן"</string> @@ -1573,7 +1580,7 @@ <string name="reset" msgid="3865826612628171429">"איפוס"</string> <string name="submit" msgid="862795280643405865">"שליחה"</string> <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"אפליקציית הנהיגה פועלת"</string> - <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"יש להקיש כדי לצאת מאפליקציית הנהיגה."</string> + <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"יש ללחוץ כדי לצאת מאפליקציית הנהיגה."</string> <string name="back_button_label" msgid="4078224038025043387">"הקודם"</string> <string name="next_button_label" msgid="6040209156399907780">"הבא"</string> <string name="skip_button_label" msgid="3566599811326688389">"דילוג"</string> @@ -1652,7 +1659,7 @@ <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_body" msgid="5338694433686077733">"יש להקיש כדי להסיר את ההגבלה."</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> <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"האפליקציה <xliff:g id="APP">%s</xliff:g> השתמשה בנתונים רבים יותר מהרגיל"</string> @@ -1748,7 +1755,7 @@ <string name="csd_dose_reached_warning" product="default" msgid="491875107583931974">"להמשיך להאזין בעוצמת קול גבוהה?\n\nעוצמת הקול של האוזניות הייתה גבוהה במשך יותר זמן מהמומלץ, מה שעלול להזיק לשמיעה"</string> <string name="csd_momentary_exposure_warning" product="default" msgid="7730840903435405501">"זוהה צליל חזק\n\nעוצמת הקול של האוזניות הייתה גבוהה מהמומלץ, מה שעלול להזיק לשמיעה"</string> <string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"להשתמש בקיצור הדרך לתכונת הנגישות?"</string> - <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"כשקיצור הדרך מופעל, לחיצה על שני לחצני עוצמת הקול למשך שלוש שניות מפעילה את תכונת הנגישות."</string> + <string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"כשקיצור הדרך מופעל, לחיצה על שני כפתורי עוצמת הקול למשך שלוש שניות מפעילה את תכונת הנגישות."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"האם להפעיל את מקש הקיצור לתכונות הנגישות?"</string> <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"לחיצה ארוכה על שני לחצני עוצמת הקול למשך מספר שניות מפעילה את תכונות הנגישות. בעקבות זאת, ייתכן שאופן הפעולה של המכשיר ישתנה.\n\nהתכונות הנוכחיות:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nניתן לשנות את התכונות שנבחרו ב\'הגדרות\' > \'נגישות\'."</string> <string name="accessibility_shortcut_multiple_service_list" msgid="2128323171922023762">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string> @@ -1768,8 +1775,8 @@ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"עדיף שלא"</string> <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"הסרה"</string> <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"אפליקציה מסתירה את בקשת ההרשאה כך שלא ניתן לאמת את התשובה שלך."</string> - <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"יש להקיש על תכונה כדי להתחיל להשתמש בה:"</string> - <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"בחירת תכונה לשימוש עם לחצן הנגישות"</string> + <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"יש ללחוץ על תכונה כדי להתחיל להשתמש בה:"</string> + <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"בחירת תכונה לשימוש עם כפתור הנגישות"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="2245540598834891500">"בחירת תכונות לשימוש עם קיצור דרך באמצעות מקשי עוצמת הקול"</string> <string name="accessibility_uncheck_legacy_item_warning" msgid="8047830891064817447">"שירות <xliff:g id="SERVICE_NAME">%s</xliff:g> כבוי"</string> <string name="edit_accessibility_shortcut_menu_button" msgid="8885752738733772935">"עריכת קיצורי הדרך"</string> @@ -1781,24 +1788,32 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"מצב שימוש ביד אחת"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"מעומעם במיוחד"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"מכשירי שמיעה"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"מנותק"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"מחובר"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"פעיל"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"בטעינה"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"אפשר לשחרר את מקש עוצמת הקול. כדי להפעיל את השירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, צריך ללחוץ לחיצה ארוכה על שני המקשים של עוצמת הקול שוב במשך 3 שניות."</string> <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"בחירת תכונה"</string> <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"בחירת תכונה"</string> <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"בחירת תכונה"</string> - <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"התכונה תיפתח בפעם הבאה שתזוהה הקשה על לחצן הנגישות"</string> + <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"התכונה תיפתח בפעם הבאה שתזוהה לחיצה על כפתור הנגישות"</string> <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 2 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 3 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"הגדלה"</string> + <!-- no translation found for hearing_device_switch_phone_mic_notification_title (6645178038359708836) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_title (4612074852145289569) --> + <skip /> + <!-- no translation found for hearing_device_switch_phone_mic_notification_text (1332426273666077412) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_text (8288368365767284208) --> + <skip /> + <!-- no translation found for hearing_device_notification_switch_button (3619524619430941300) --> + <skip /> + <!-- no translation found for hearing_device_notification_settings_button (6673651052880279178) --> + <skip /> <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> @@ -1908,7 +1923,7 @@ <string name="reason_unknown" msgid="5599739807581133337">"לא ידוע"</string> <string name="reason_service_unavailable" msgid="5288405248063804713">"שירות ההדפסה לא הופעל"</string> <string name="print_service_installed_title" msgid="6134880817336942482">"שירות <xliff:g id="NAME">%s</xliff:g> מותקן"</string> - <string name="print_service_installed_message" msgid="7005672469916968131">"יש להקיש כדי להפעיל את השירות"</string> + <string name="print_service_installed_message" msgid="7005672469916968131">"יש ללחוץ כדי להפעיל את השירות"</string> <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"יש להזין את קוד האימות של מנהל המכשיר"</string> <string name="restr_pin_enter_pin" msgid="373139384161304555">"יש להזין קוד אימות"</string> <string name="restr_pin_incorrect" msgid="3861383632940852496">"שגוי"</string> @@ -1946,7 +1961,7 @@ <string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string> <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים, תכונות מסוימות וחלק מהחיבורים לרשתות."</string> <string name="battery_saver_description" msgid="8518809702138617167">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים, תכונות מסוימות וחלק מהחיבורים לרשתות."</string> - <string name="data_saver_description" msgid="4995164271550590517">"כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות לשלוח או לקבל נתונים ברקע. אפליקציות שבהן נעשה שימוש כרגע יכולות לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שמקישים עליהן."</string> + <string name="data_saver_description" msgid="4995164271550590517">"כדי לסייע בהפחתת השימוש בנתונים, חוסך הנתונים (Data Saver) מונע מאפליקציות מסוימות לשלוח או לקבל נתונים ברקע. אפליקציות שבהן נעשה שימוש כרגע יכולות לגשת לנתונים, אבל בתדירות נמוכה יותר. המשמעות היא, למשל, שתמונות יוצגו רק לאחר שלוחצים עליהן."</string> <string name="data_saver_enable_title" msgid="7080620065745260137">"להפעיל את חוסך הנתונים?"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"הפעלה"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{למשך דקה אחת (עד {formattedTime})}one{למשך # דקות (עד{formattedTime})}two{למשך # דקות (עד{formattedTime})}other{למשך # דקות (עד{formattedTime})}}"</string> @@ -2076,9 +2091,9 @@ <string name="new_sms_notification_content" msgid="3197949934153460639">"יש לפתוח את אפליקציית ה-SMS כדי להציג"</string> <string name="profile_encrypted_title" msgid="9001208667521266472">"ייתכן שחלק מהפונקציונליות תהיה מוגבלת"</string> <string name="profile_encrypted_detail" msgid="5279730442756849055">"פרופיל העבודה נעול"</string> - <string name="profile_encrypted_message" msgid="1128512616293157802">"יש להקיש לביטול נעילת פרופיל העבודה"</string> + <string name="profile_encrypted_message" msgid="1128512616293157802">"יש ללחוץ לביטול נעילת פרופיל העבודה"</string> <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"התבצע חיבור אל <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string> - <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"יש להקיש כדי להציג קבצים"</string> + <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"יש ללחוץ כדי להציג קבצים"</string> <string name="pin_target" msgid="8036028973110156895">"הצמדה"</string> <string name="pin_specific_target" msgid="7824671240625957415">"הצמדה של <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="unpin_target" msgid="3963318576590204447">"ביטול הצמדה"</string> @@ -2165,7 +2180,7 @@ <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"שיחות והתראות יושתקו"</string> <string name="notification_channel_system_changes" msgid="2462010596920209678">"שינויים במערכת"</string> <string name="review_notification_settings_title" msgid="5102557424459810820">"בדיקת הגדרת ההתראות"</string> - <string name="review_notification_settings_text" msgid="5916244866751849279">"החל מגרסת Android 13, אפליקציות שיותקנו יוכלו לשלוח התראות רק אם יקבלו ממך הרשאה. אפשר להקיש כדי לשנות את ההרשאה הזו באפליקציות קיימות."</string> + <string name="review_notification_settings_text" msgid="5916244866751849279">"החל מגרסת Android 13, אפליקציות שיותקנו יוכלו לשלוח התראות רק אם יקבלו ממך הרשאה. אפשר ללחוץ כדי לשנות את ההרשאה הזו באפליקציות קיימות."</string> <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"תזכירו לי מאוחר יותר"</string> <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"סגירה"</string> <string name="notification_app_name_system" msgid="3045196791746735601">"מערכת"</string> @@ -2174,10 +2189,10 @@ <string name="notification_appops_microphone_active" msgid="581333393214739332">"מיקרופון"</string> <string name="notification_appops_overlay_active" msgid="5571732753262836481">"תצוגה מעל אפליקציות אחרות במסך"</string> <string name="notification_feedback_indicator" msgid="663476517711323016">"שליחת משוב"</string> - <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"ההתראה הזו שודרגה ל\'ברירת מחדל\'. יש להקיש כדי לשלוח משוב."</string> - <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ההתראה הזו הורדה בדרגה ל\'שקטה\'. יש להקיש כדי לשלוח משוב."</string> - <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"דירוג ההתראה הזו הוגבה. יש להקיש כדי לשלוח משוב."</string> - <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ההתראה הזו דורגה נמוך יותר. יש להקיש כדי לשלוח משוב."</string> + <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"ההתראה הזו שודרגה ל\'ברירת מחדל\'. יש ללחוץ כדי לשלוח משוב."</string> + <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"ההתראה הזו הורדה בדרגה ל\'שקטה\'. יש ללחוץ כדי לשלוח משוב."</string> + <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"דירוג ההתראה הזו הוגבה. יש ללחוץ כדי לשלוח משוב."</string> + <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"ההתראה הזו דורגה נמוך יותר. יש ללחוץ כדי לשלוח משוב."</string> <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"התראות משופרות"</string> <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"ההתראות המשופרות מספקות מעכשיו הצעות לפעולות ולתשובות. אין יותר תמיכה בהתראות מותאמות ל-Android."</string> <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"אישור"</string> @@ -2394,14 +2409,14 @@ <string name="splash_screen_view_icon_description" msgid="180638751260598187">"סמל האפליקציה"</string> <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"תדמית המותג של האפליקציה"</string> <string name="view_and_control_notification_title" msgid="4300765399209912240">"בדיקה של הגדרות הגישה"</string> - <string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יש הרשאה להצגת המסך ושליטה בו. אפשר להקיש כדי לבדוק."</string> + <string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יש הרשאה להצגת המסך ושליטה בו. אפשר ללחוץ כדי לבדוק."</string> <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"ההודעה <xliff:g id="MESSAGE">%1$s</xliff:g> תורגמה."</string> <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ההודעה תורגמה מ<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ל<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string> <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"פעילות ברקע"</string> <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"אחת האפליקציות מרוקנת את הסוללה"</string> <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"אפליקציה כלשהי עדיין פעילה"</string> - <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> פועלת ברקע. יש להקיש כדי לנהל את השימוש בסוללה."</string> - <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> עלולה להשפיע על חיי הסוללה. אפשר להקיש כדי לבדוק את האפליקציות הפעילות."</string> + <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> פועלת ברקע. יש ללחוץ כדי לנהל את השימוש בסוללה."</string> + <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> עלולה להשפיע על חיי הסוללה. אפשר ללחוץ כדי לבדוק את האפליקציות הפעילות."</string> <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"כדאי לבדוק את האפליקציות הפעילות"</string> <string name="vdm_camera_access_denied" product="default" msgid="6102378580971542473">"לא ניתן לגשת למצלמה של הטלפון מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string> <string name="vdm_camera_access_denied" product="tablet" msgid="6895968310395249076">"לא ניתן לגשת למצלמה של הטאבלט מה‑<xliff:g id="DEVICE">%1$s</xliff:g>"</string> @@ -2432,12 +2447,12 @@ <string name="device_state_notification_settings_button" msgid="691937505741872749">"מעבר להגדרות"</string> <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"השבתה"</string> <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"המקלדת <xliff:g id="DEVICE_NAME">%s</xliff:g> הוגדרה"</string> - <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string> - <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string> - <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string> - <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… אפשר להקיש כדי לשנות את ההגדרה הזו."</string> + <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%s</xliff:g>. אפשר ללחוץ כדי לשנות את ההגדרה הזו."</string> + <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. אפשר ללחוץ כדי לשנות את ההגדרה הזו."</string> + <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. אפשר ללחוץ כדי לשנות את ההגדרה הזו."</string> + <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… אפשר ללחוץ כדי לשנות את ההגדרה הזו."</string> <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"הוגדרו מקלדות פיזיות"</string> - <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"יש להקיש כדי להציג את המקלדות"</string> + <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"יש ללחוץ כדי להציג את המקלדות"</string> <string name="profile_label_private" msgid="6463418670715290696">"פרטי"</string> <string name="profile_label_clone" msgid="769106052210954285">"שכפול"</string> <string name="profile_label_work" msgid="3495359133038584618">"פרופיל עבודה"</string> @@ -2455,6 +2470,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"תוכן האפליקציה מוסתר משיתוף המסך מטעמי אבטחה"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"חיבור אוטומטי ללוויין"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"אפשר לשלוח ולקבל הודעות ללא רשת סלולרית או רשת Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"רוצה לשלוח הודעות באמצעות תקשורת לוויינית?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"אפשר לשלוח ולקבל הודעות ללא רשת סלולרית או Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"לפתיחת Messages"</string> @@ -2500,7 +2517,7 @@ <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"שעון מעורר של <xliff:g id="USER_NAME">%s</xliff:g>"</string> <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"החלפת משתמש"</string> <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"השתקה"</string> - <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"כדי להשתיק את הצליל, צריך להקיש כאן"</string> + <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"כדי להשתיק את הצליל, צריך ללחוץ כאן"</string> <string name="keyboard_shortcut_group_applications_browser" msgid="6535007304687100909">"דפדפן"</string> <string name="keyboard_shortcut_group_applications_contacts" msgid="2750702518068326356">"אנשי קשר"</string> <string name="keyboard_shortcut_group_applications_email" msgid="4229037666415353683">"אימייל"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 05adb2b13e4d..51dca2255a83 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"モバイル ネットワークにアクセスできません"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"タップして、優先ネットワークを変更してください。"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"緊急通報は利用できません"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"今後表示しない"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"緊急通報にはモバイル ネットワークが必要です"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"電話の転送"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ネットワーク通知"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ネットワークを利用できます"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN のステータス"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"時刻とタイムゾーン"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT 管理者からの通知"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"通知"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"販売店デモ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"実行中のアプリ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"電池を消費しているアプリ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"拡大"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"補聴器"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ユーザー補助の使用"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ディスプレイ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」がバッテリーを使用しています"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"アプリをダウンロード"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"新しい SIM が挿入されました"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"タップして設定"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"タイムゾーンを変更しました"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g>(<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)に変更しました"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"時刻設定"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"日付設定"</string> <string name="date_time_set" msgid="4603445265164486816">"設定"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"片手モード"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"さらに輝度を下げる"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"補聴器"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"未接続"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"接続済み"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"有効"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"読み込んでいます"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"音量ボタンを離してください。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を有効にするには音量大と音量小の両方のボタンを 3 秒ほど長押ししてください。"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"この機能は、このショートカットを次回使用した時に利用できるようになります。2 本の指で画面の下部から上にスワイプし、素早く離してください。"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"この機能は、このショートカットを次回使用した時に利用できるようになります。3 本の指で画面の下部から上にスワイプし、素早く離してください。"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"拡大"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"スマートフォンのマイクに切り替えますか?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"補聴器のマイクに切り替えますか?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"音質を向上させるために、または補聴器のバッテリー残量が少ない場合に使用します。通話時のみマイクが切り替わります。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"補聴器のマイクを使ってハンズフリー通話を行えます。通話時のみマイクが切り替わります。"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切り替える"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string> <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> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"セキュリティ上、画面共有ではアプリの内容は非表示となります"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"衛星に自動接続しました"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"モバイル ネットワークや Wi-Fi ネットワークを使わずにメッセージを送受信できます"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"衛星経由でのメッセージの送受信とデータの使用(上限あり)が可能です"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"衛星通信メッセージを使用しますか?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"モバイル ネットワークや Wi-Fi ネットワークがなくてもメッセージを送受信できます"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"メッセージ アプリを開く"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 552f52e0c128..2411c8cad961 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"მობილურ ქსელთან დაკავშირება ვერ ხერხდება"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ცადეთ უპირატესი ქსელის შეცვლა. შეეხეთ შესაცვლელად."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"გადაუდებელი ზარი მიუწვდომელია"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"აღარ გამოჩნდეს"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"გადაუდებელი ზარები საჭიროებს მობილურ ქსელს"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"გაფრთხილებები"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ზარის გადამისამართება"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ქსელის გაფრთხილებები"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ქსელი ხელმისაწვდომია"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-ის სტატუსი"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"დრო და სასაათო სარტყელი"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"გაფრთხილებები თქვენი IT ადმინისტრატორისგან"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"გაფრთხილებები"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"დემო-რეჟიმი საცალო მოვაჭრეებისთვის"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"აპი გაშვებულია"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ბატარეის მხარჯავი აპები"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"გადიდება"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"სმენის აპარატი"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"მარტივი წვდომის გამოყენება"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ეკრანი"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ბატარეას"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"აპის ჩამოტვირთვა"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"მოთავსებულია ახალი SIM ბარათი"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"შეეხეთ პარამეტრების დასაყენებლად"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"თქვენი სასაათო სარტყელი შეიცვალა"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"თქვენ ახლა იმყოფებით შემდეგ სასაათო სარტყელში: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"დროის დაყენება"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"თარიღის დაყენება"</string> <string name="date_time_set" msgid="4603445265164486816">"დაყენება"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ცალი ხელის რეჟიმი"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"დამატებითი დაბინდვა"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"სმენის აპარატები"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"კავშირი გაწყვეტილია"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"დაკავშირებული"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"აქტიური"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"იტვირთება"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ხელი აუშვით ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-ის ჩასართველად, ხელმეორედ ხანგრძლივად დააჭირეთ ორივე ხმის ღილაკს 3 წამის განმავლობაში."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 2 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 3 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"გადიდება"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"გსურთ ტელეფონის მიკროფონზე გადართვა?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"გსურთ სმენის მოწყობილობის მიკროფონზე გადართვა?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"უკეთესი ხმისთვის ან, თუ თქვენი სმენის მოწყობილობის ბატარეა სუსტადაა დამუხტული. ეს გადართავს თქვენს მიკროფონს მხოლოდ ზარის დროს."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"შეგიძლიათ სმენის მოწყობილობის მიკროფონის გამოყენება უკონტაქტოდ დასარეკად. ეს გადართავს თქვენს მიკროფონს მხოლოდ ზარის დროს."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"გადართვა"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"პარამეტრები"</string> <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> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებისას აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"სატელიტთან ავტომატურად დაკავშირებულია"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები და გამოიყენოთ შეზღუდული მონაცემები სატელიტით"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"გსურთ შეტყობინებების სატელიტური მიმოცვლის გამოყენება?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"შეტყობინებების გაგზავნა და მიღება მობილური ან Wi-Fi ქსელის გარეშე"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 3c118ac715b5..e1fd8d1a8d82 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильдік желіге қосылу мүмкін емес"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Таңдаулы желіні өзгертіп көріңіз. Өзгерту үшін түртіңіз."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Жедел қызметке қоңырау шалу мүмкін емес"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Қайта көрсетілмесін"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Құтқару қызметіне қоңырау шалу үшін мобильдік желі қажет."</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Дабылдар"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Қоңырауды басқа нөмірге бағыттау"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Желі дабылдары"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Желі қолжетімді"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN күйі"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Уақыт және уақыт белдеулері"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"АТ әкімшісі жіберген ескертулер"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Дабылдар"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Бөлшек саудаға арналған демо нұсқасы"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Қолданба қосулы"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Батареяны пайдаланып жатқан қолданбалар"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ұлғайту"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Есту құрылғысы"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Арнайы мүмкіндіктерді қолдану"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Дисплей"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батареяны пайдалануда"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Қолданбаны жүктеп алу"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Жаңа SIM салынды"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Оны орнату үшін түртіңіз"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Уақыт белдеуі өзгертілді"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Қазір <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) уақыт белдеуіндесіз."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Уақытты реттеу"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Мезгілін реттеу"</string> <string name="date_time_set" msgid="4603445265164486816">"Орнату"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бір қолмен басқару режимі"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Экранды қарайту"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Есту аппараттары"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ажыратылды"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Қосылды"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Белсенді"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Жүктеліп жатыр"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дыбыс деңгейі пернелерін жіберіңіз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосу үшін дыбыс деңгейі пернесінің екеуін де қайтадан 3 секундқа басып тұрыңыз."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 2 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 3 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефонның микрофонына ауысу керек пе?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Есту аппаратының микрофонына ауысу керек пе?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дауыс жақсы шығу үшін немесе есту аппаратының батарея заряды аз болған жағдайда пайдалануға болады. Микрофонға тек қоңырау кезінде ауысады."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Микрофонға тек қоңырау кезінде ауысады."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Ауысу"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Қауіпсіздік мақсатында қолданба контенті экранды көрсету кезінде жасырылды."</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Жерсерік қызметіне автоматты түрде қосылды"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Мобильдік не Wi-Fi желісіне қосылмастан хабар жібере аласыз және ала аласыз."</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Жерсерік арқылы хабар алмасасыз ба?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Хабарландыруларды мобильдік желіге немесе Wi-Fi желісіне қосылмай жіберіңіз және алыңыз."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 737fe883930c..190693976be1 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"មិនអាចភ្ជាប់បណ្ដាញទូរសព្ទចល័តបានទេ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"សាកល្បងប្ដូរទៅបណ្ដាញដែលចង់ប្រើ។ សូមចុចដើម្បីផ្លាស់ប្ដូរ។"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"មិនអាចប្រើការហៅបន្ទាន់បានទេ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"កុំបង្ហាញទៀត"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ការហៅទៅលេខសង្គ្រោះបន្ទាន់តម្រូវឱ្យមានបណ្ដាញទូរសព្ទចល័ត"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ការជូនដំណឹង"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ការបញ្ជូនការហៅទូរសព្ទបន្ត"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ការជូនដំណឹងអំពីបណ្តាញ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"មានបណ្តាញ"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"ស្ថានភាព VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ម៉ោង និងល្វែងម៉ោង"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ការជូនដំណឹងពីអ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នក"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ការជូនដំណឹង"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"របៀបដាក់បង្ហាញក្នុងហាង"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"កម្មវិធីដែលកំពុងដំណើរការ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"កម្មវិធីដែលកំពុងប្រើថ្ម"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ការពង្រីក"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"ឧបករណ៍ជំនួយការស្ដាប់"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ការប្រើប្រាស់ភាពងាយស្រួល"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ផ្ទាំងអេក្រង់"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើថ្ម"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ទាញយកកម្មវិធី"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ស៊ីមកាតថ្មីត្រូវបានស៊កចូល"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ប៉ះដើម្បីដំឡើង"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"ល្វែងម៉ោងរបស់អ្នកបានផ្លាស់ប្ដូរ"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ឥឡូវនេះ អ្នកស្ថិតនៅ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"កំណត់ម៉ោង"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"កំណត់កាលបរិច្ឆេទ"</string> <string name="date_time_set" msgid="4603445265164486816">"កំណត់"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"មុខងារប្រើដៃម្ខាង"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ងងឹតខ្លាំង"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ឧបករណ៍ជំនួយការស្ដាប់"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"បានផ្ដាច់"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"បានភ្ជាប់"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"សកម្ម"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"កំពុងផ្ទុក"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"លែងគ្រាប់ចុចកម្រិតសំឡេង។ ដើម្បីបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g> សូមចុចគ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់ម្ដងទៀតរយៈពេល 3 វិនាទី។"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 2 ហើយលែងឱ្យរហ័ស។"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 3 ហើយលែងឱ្យរហ័ស។"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ការពង្រីក"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ប្ដូរទៅមីក្រូហ្វូនទូរសព្ទឬ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ប្ដូរទៅមីក្រូហ្វូនឧបករណ៍ជំនួយការស្ដាប់ឬ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ដើម្បីទទួលបានសំឡេងកាន់តែប្រសើរ ឬប្រសិនបើថ្មឧបករណ៍ជំនួយការស្ដាប់របស់អ្នកជិតអស់។ ការធ្វើបែបនេះប្ដូរមីក្រូហ្វូនរបស់អ្នក ក្នុងអំឡុងការហៅទូរសព្ទតែប៉ុណ្ណោះ។"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"អ្នកអាចប្រើមីក្រូហ្វូនឧបករណ៍ជំនួយការស្ដាប់របស់អ្នកសម្រាប់ការហៅទូរសព្ទដោយមិនប្រើដៃ។ ការធ្វើបែបនេះប្ដូរមីក្រូហ្វូនរបស់អ្នក ក្នុងអំឡុងការហៅទូរសព្ទតែប៉ុណ្ណោះ។"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ប្ដូរ"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ការកំណត់"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"បានលាក់ខ្លឹមសារកម្មវិធីពីការបង្ហាញអេក្រង់ដើម្បីសុវត្ថិភាព"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ភ្ជាប់ដោយស្វ័យប្រវត្តិទៅផ្កាយរណប"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"អ្នកអាចផ្ញើ និងទទួលសារដោយមិនប្រើបណ្តាញទូរសព្ទចល័ត ឬ Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ប្រើការផ្ញើសារតាមផ្កាយរណបឬ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ផ្ញើ និងទទួលសារដោយគ្មានបណ្ដាញ Wi-Fi ឬបណ្ដាញទូរសព្ទចល័ត"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"បើកកម្មវិធី Messages"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 87a0bef2ceb6..9c11160f502d 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ಆದ್ಯತೆಗೊಳಿಸಿದ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಪ್ರಯತ್ನಿಸಿ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ತುರ್ತು ಕರೆ ಮಾಡುವಿಕೆ ಲಭ್ಯವಿಲ್ಲ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ಪುನಃ ತೋರಿಸಬೇಡಿ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ತುರ್ತು ಕರೆಗಳಿಗೆ ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ನ ಅಗತ್ಯವಿದೆ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ಎಚ್ಚರಿಕೆಗಳು"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ಕರೆ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ನೆಟ್ವರ್ಕ್ ಎಚ್ಚರಿಕೆಗಳು"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ನೆಟ್ವರ್ಕ್ ಲಭ್ಯವಿದೆ"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN ಸ್ಥಿತಿ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ಸಮಯ ಹಾಗೂ ಸಮಯ ವಲಯಗಳು"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ನಿಮ್ಮ IT ವಿಭಾಗದ ನಿರ್ವಾಹಕರಿಂದ ಎಚ್ಚರಿಕೆಗಳು"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ಎಚ್ಚರಿಕೆಗಳು"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"ರಿಟೇಲ್ ಡೆಮೋ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App ರನ್ ಆಗುತ್ತಿದೆ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಬ್ಯಾಟರಿಯನ್ನು ಉಪಯೋಗಿಸುತ್ತಿವೆ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"ಹಿಯರಿಂಗ್ ಸಾಧನ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ಪ್ರವೇಶಿಸುವಿಕೆಯ ಬಳಕೆ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ಡಿಸ್ಪ್ಲೇ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್, ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸುತ್ತಿದೆ"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ಆ್ಯಪ್ ಡೌನ್ಲೋಡ್ ಮಾಡಿ"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ಹೊಸ ಸಿಮ್ ಸೇರಿಸಲಾಗಿದೆ"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ಇದನ್ನು ಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"ನಿಮ್ಮ ಸಮಯವಲಯ ಬದಲಾಗಿದೆ."</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ನೀವು ಈಗ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ನಲ್ಲಿದ್ದೀರಿ"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ಸಮಯವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ದಿನಾಂಕವನ್ನು ಸೆಟ್ ಮಾಡಿ"</string> <string name="date_time_set" msgid="4603445265164486816">"ಹೊಂದಿಸು"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ಒಂದು ಕೈ ಮೋಡ್"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ಇನ್ನಷ್ಟು ಮಬ್ಬು"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ಶ್ರವಣ ಸಾಧನಗಳು"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ಡಿಸ್ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ಸಕ್ರಿಯವಾಗಿದೆ"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ಲೋಡ್ ಆಗುತ್ತಿದೆ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಮತ್ತೊಮ್ಮೆ 3 ಸೆಕೆಂಡ್ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ 2 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ 3 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ಫೋನ್ ಮೈಕ್ಗೆ ಬದಲಿಸಬೇಕೆ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ಶ್ರವಣ ಸಾಧನ ಮೈಕ್ಗೆ ಬದಲಿಸಬೇಕೆ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ಉತ್ತಮ ಧ್ವನಿಗಾಗಿ ಅಥವಾ ನಿಮ್ಮ ಶ್ರವಣ ಸಾಧನದ ಬ್ಯಾಟರಿ ಕಡಿಮೆಯಿದ್ದರೆ. ಇದು ಕರೆಯ ಸಮಯದಲ್ಲಿ ಮಾತ್ರ ನಿಮ್ಮ ಮೈಕ್ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ಹ್ಯಾಂಡ್ಸ್-ಫ್ರೀ ಕರೆ ಮಾಡುವಿಕೆಗಾಗಿ ನಿಮ್ಮ ಶ್ರವಣ ಸಾಧನದ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ನೀವು ಬಳಸಬಹುದು. ಇದು ಕರೆಯ ಸಮಯದಲ್ಲಿ ಮಾತ್ರ ನಿಮ್ಮ ಮೈಕ್ ಅನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ಬದಲಿಸಿ"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ಭದ್ರತೆಗಾಗಿ ಸ್ಕ್ರೀನ್ ಹಂಚಿಕೊಳ್ಳುವಿಕೆಯಲ್ಲಿ ಆ್ಯಪ್ ಕಂಟೆಂಟ್ ಅನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ಸ್ಯಾಟಲೈಟ್ಗೆ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ನೀವು ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ಸ್ವೀಕರಿಸಬಹುದು"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ಸ್ಯಾಟಲೈಟ್ ಮೆಸೇಜಿಂಗ್ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಿ ಮತ್ತು ಸ್ವೀಕರಿಸಿ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 51921be8b6b4..1b302e633fa7 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"모바일 네트워크에 연결할 수 없습니다."</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"기본 네트워크를 변경해 보세요. 탭하여 변경할 수 있습니다."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"긴급 전화를 사용할 수 없습니다."</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"다시 표시 안 함"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"긴급 전화를 걸려면 모바일 네트워크 연결이 필요함"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"알림"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"착신전환"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"네트워크 알림"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"네트워크 사용 가능"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN 상태"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"시간 및 시간대"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT 관리자가 보낸 알림"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"알림"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"소매 데모"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"실행 중인 앱"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"배터리를 소모하는 앱"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"확대"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"청각 보조 기기"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"접근성 사용"</string> <string name="notification_channel_display" msgid="6905032605735615090">"디스플레이"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 배터리 사용 중"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"앱 다운로드"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"새 SIM이 삽입됨"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"탭하여 설정"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"시간대가 변경되었습니다"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"현재 시간대는 <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g>(<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)입니다."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"시간 설정"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"날짜 설정"</string> <string name="date_time_set" msgid="4603445265164486816">"설정"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"한 손 모드"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"더 어둡게"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"청각 보조 기기"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"연결 끊김"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"연결됨"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"활성"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"로드 중"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"볼륨 키에서 손을 뗍니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>을 켜려면 볼륨 키 2개를 3초 동안 길게 누르세요."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 두 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 세 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"확대"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"휴대전화 마이크로 전환하시겠습니까?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"보청기 마이크로 전환하시겠습니까?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"더 나은 음질을 원하거나 보청기 배터리가 부족한 경우 전환할 수 있습니다. 통화 중에만 마이크가 전환됩니다."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"보청기 마이크로 핸즈프리 통화 기능을 이용할 수 있습니다. 통화 중에만 마이크가 전환됩니다."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"전환"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"설정"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"보안을 위해 화면 공유에서 앱 콘텐츠가 숨겨집니다."</string> <string name="satellite_notification_title" msgid="4026338973463121526">"위성에 자동 연결됨"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"모바일 또는 Wi-Fi 네트워크 없이 메시지를 주고 받을 수 있습니다"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"위성 메시지를 사용하시겠습니까?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"모바일 또는 Wi-Fi 네트워크 없이 메시지 주고받기"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"메시지 열기"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 7ca2092dddf0..58a6d8486caf 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилдик тармакка туташпай жатат"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Тандалган тармакты өзгөртүп көрүңүз. Өзгөртүү үчүн таптаңыз."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Шашылыш чалуу жеткиликсиз"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Экинчи көрүнбөсүн"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Шашылыш чалуу үчүн мобилдик тармак талап кылынат"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Шашылыш билдирүүлөр"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Чалууну башка номерге багыттоо"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Тармактын эскертүүлөрү"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Жеткиликтүү тармактар"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN абалы"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Убакыт жана убакыт алкактары"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT администраторуңуздан келген билдирүүлөр"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Шашылыш билдирүүлөр"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Чекене соода дүкөнү үчүн демо режим"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Колдонмо иштеп жатат"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Колдонмолор батареяңызды коротууда"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Чоңойтуу"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Угуу аппараты"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Атайын мүмкүнчүлүктөрдүн колдонулушу"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Экран"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу батареяны пайдаланып жатат"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Колдонмону жүктөп алуу"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Жаңы SIM карта салынды"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Аны жөндөө үчүн таптап коюңуз"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Убакыт алкагыңыз өзгөрдү"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Учурдагы убакыт алкагы: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Убакытты коюу"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Күндү коюу"</string> <string name="date_time_set" msgid="4603445265164486816">"Коюу"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Бир кол режими"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Кошумча караңгылатуу"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Угуу түзмөктөрү"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Ажыратылды"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Туташты"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Жигердүү"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Жүктөлүүдө"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Үн баскычтарын коё бериңиз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүзүү үчүн үн баскычтарын кайра 3 секунд коё бербей басып туруңуз."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 2 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 3 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефондун микрофонуна которуласызбы?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Угуу аппаратынын микрофонуна которуласызбы?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Үндүн сапатын жакшыртуу үчүн же угуу аппаратыңыздын батареясы аз болсо, телефондун микрофонун колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Угуу аппаратыңыздын микрофонун үн режиминде чалуу үчүн колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Которулуу"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Коопсуздук үчүн колдонмодогу контент бөлүшүлгөн экрандан жашырылды"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Спутникке автоматтык түрдө туташтырылган"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Сиз мобилдик же Wi-Fi тармагы жок эле билдирүүлөрдү жөнөтүп, ала аласыз"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Спутник аркылуу байланышасызбы?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Мобилдик же Wi-Fi тармагына туташпай эле билдирүүлөрдү жөнөтүп, алыңыз"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Жазышуулар колдонмосун ачуу"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 32b0605b1128..3c3c58ba281a 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ບໍ່ສາມາດຕິດຕໍ່ເຄືອຂ່າຍມືຖືໄດ້"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ໃຫ້ລອງປ່ຽນເຄືອຂ່າຍທີ່ຕ້ອງການ. ແຕະເພື່ອປ່ຽນ."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ບໍ່ສາມາດໃຊ້ການໂທສຸກເສີນໄດ້"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ບໍ່ຕ້ອງສະແດງອີກ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ໂທສຸກເສີນຕ້ອງໃຊ້ເຄືອຂ່າຍມືຖື"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ການເຕືອນ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ການໂອນສາຍ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ແຈ້ງເຕືອນເຄືອຂ່າຍ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ມີເຄືອຂ່າຍທີ່ສາມາດໃຊ້ໄດ້"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"ສະຖານະ VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ເວລາ ແລະ ເຂດເວລາ"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ການເຕືອນຈາກຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ການເຕືອນ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"ເດໂມສຳລັບຮ້ານຂາຍ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ແອັບກຳລັງເຮັດວຽກ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ແອັບທີ່ກຳລັງໃຊ້ແບັດເຕີຣີ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ການຂະຫຍາຍ"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"ອຸປະກອນຊ່ວຍຟັງ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ການໃຊ້ການຊ່ວຍເຂົ້າເຖິງ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ຈໍສະແດງຜົນ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ແບັດເຕີຣີຢູ່"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ດາວໂຫລດແອັບ"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ໃສ່ SIM ໃໝ່ແລ້ວ"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ແຕະເພື່ອຕັ້ງມັນ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"ເຂດເວລາຂອງທ່ານມີການປ່ຽນແປງ"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ຕອນນີ້ທ່ານຢູ່ໃນເຂດເວລາ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ຕັ້ງເວລາ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ກໍານົດວັນທີ"</string> <string name="date_time_set" msgid="4603445265164486816">"ຕັ້ງຄ່າ"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ໂໝດມືດຽວ"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ຫຼຸດແສງເປັນພິເສດ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ອຸປະກອນຊ່ວຍຟັງ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ຕັດການເຊື່ອມຕໍ່ແລ້ວ"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"ເຊື່ອມຕໍ່ແລ້ວ"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ນຳໃຊ້ຢູ່"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ກຳລັງໂຫຼດ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ປ່ອຍປຸ່ມລະດັບສຽງ. ເພື່ອເປີດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ໃຫ້ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີ."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 2 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 3 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ການຂະຫຍາຍ"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ປ່ຽນໄປໃຊ້ໄມໂຄຣໂຟນຂອງໂທລະສັບບໍ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ປ່ຽນໄປໃຊ້ໄມໂຄຣໂຟນຂອງເຄື່ອງຊ່ວຍຟັງບໍ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ເພື່ອໃຫ້ສຽງດີຂຶ້ນ ຫຼື ໃນກໍລະນີທີ່ແບັດເຕີຣີຂອງເຄື່ອງຊ່ວຍຟັງຂອງທ່ານໃກ້ໝົດ. ການດຳເນີນການນີ້ພຽງແຕ່ປ່ຽນໄມໂຄຣໂຟນຂອງທ່ານໃນລະຫວ່າງການໂທເທົ່ານັ້ນ."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ທ່ານສາມາດໃຊ້ໄມໂຄຣໂຟນຂອງເຄື່ອງຊ່ວຍຟັງເພື່ອການໂທແບບແຮນຟຣີໄດ້. ການດຳເນີນການນີ້ພຽງແຕ່ປ່ຽນໄມໂຄຣໂຟນຂອງທ່ານໃນລະຫວ່າງການໂທເທົ່ານັ້ນ."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ປ່ຽນ"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ການຕັ້ງຄ່າ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ເນື້ອຫາແອັບຖືກເຊື່ອງໄວ້ຈາກການແບ່ງປັນໜ້າຈໍເພື່ອຄວາມປອດໄພ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ເຊື່ອມຕໍ່ກັບດາວທຽມໂດຍອັດຕະໂນມັດ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ທ່ານສາມາດສົ່ງ ແລະ ຮັບຂໍ້ຄວາມໂດຍບໍ່ຕ້ອງໃຊ້ເຄືອຂ່າຍມືຖື ຫຼື Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ໃຊ້ການຮັບສົ່ງຂໍ້ຄວາມຜ່ານດາວທຽມບໍ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ຮັບ ແລະ ສົ່ງຂໍ້ຄວາມໂດຍບໍ່ຕ້ອງໃຊ້ເຄືອຂ່າຍໂທລະສັບມືຖື ຫຼື Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"ເປີດ Messages"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index ff7919e4e55a..3c56808d883e 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepavyko pasiekti mobiliojo ryšio tinklo"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pabandykite pakeisti pageidaujamą tinklą. Palieskite, kad pakeistumėte."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Skambučių pagalbos numeriu paslauga nepasiekiama"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Daugiau nerodyti"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Kad būtų galima skambinti pagalbos numeriais, būtina naudoti mobiliojo ryšio tinklą"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Įspėjimai"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Skambučio peradresavimas"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Tinklo įspėjimai"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Tinklas pasiekiamas"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN būsena"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Laikas ir laiko juostos"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT administratoriaus įspėjimai"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Įspėjimai"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstracinė versija mažmenininkams"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Programa paleista"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programos, naudojančios akumuliatoriaus energiją"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Didinimas"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Klausos įrenginys"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Pritaikomumo funkcijų naudojimas"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekranas"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja akumuliatoriaus energiją"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Atsisiųsti programą"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Įdėta nauja SIM kortelė"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Jei norite tai nustatyti, palieskite"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Jūsų laiko juosta pakeista"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Dabar esate <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Nustatyti laiką"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Nustatyti datą"</string> <string name="date_time_set" msgid="4603445265164486816">"Nustatyti"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienos rankos režimas"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Itin blanku"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Klausos įrenginiai"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Atjungta"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Prisijungta"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktyvus"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Įkeliama"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atleiskite garsumo klavišus. Kad įjungtumėte „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite ir 3 sekundes palaikykite garsumo klavišus."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite dviem pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite trimis pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Didinimas"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Perjungti į telefono mikrofoną?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Perjungti į klausos aparato mikrofoną?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Kad būtų geresnis garsas arba jei klausos aparato akumuliatorius beveik išsikrovęs. Mikrofonas įjungiamas tik per skambutį."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Galite naudoti klausos aparato mikrofoną skambučiams laisvų rankų režimu. Mikrofonas įjungiamas tik per skambutį."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Perjungti"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nustatymai"</string> <string name="user_switched" msgid="7249833311585228097">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Atsijungiama (<xliff:g id="NAME">%1$s</xliff:g>)…"</string> @@ -2456,6 +2461,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Programos turinys paslėptas bendrinant ekraną saugumo sumetimais"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiškai prisijungta prie palydovinio ryšio"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Galite siųsti ir gauti pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Naudoti susirašinėjimą palydoviniais pranešimais?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Siųskite ir gaukite pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index ab2c242cb55c..1870883fcc5e 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nevar sasniegt mobilo tīklu"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Mēģiniet nomainīt vēlamo tīklu. Pieskarieties, lai to mainītu."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nav pieejami ārkārtas izsaukumi"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Vairs nerādīt"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Lai veiktu ārkārtas zvanus, ir nepieciešams mobilais tīkls."</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Brīdinājumi"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Zvanu pāradresācija"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Tīkla brīdinājumi"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Tīkls ir pieejams"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN statuss"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Laiks un laika joslas"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Brīdinājumi no jūsu IT administratora"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Brīdinājumi"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstrācijas versija veikaliem"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Lietotne darbojas"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Lietotnes, kas patērē akumulatora jaudu"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Palielinājums"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Dzirdes aparāts"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Pieejamības lietojums"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Displejs"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> izmanto akumulatoru"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Lejupielādēt lietotni"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Ievietota jauna SIM karte"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Pieskarieties, lai to iestatītu."</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Jūsu laika josla ir mainīta"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Jūs tagad atrodaties šajā laika joslā: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Iestatīt laiku"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Datuma iestatīšana"</string> <string name="date_time_set" msgid="4603445265164486816">"Iestatīt"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Vienas rokas režīms"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Papildu aptumšošana"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dzirdes aparāti"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Atvienota"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Pievienota"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktīva"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Notiek ielāde"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atlaidiet skaļuma pogas. Lai ieslēgtu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vēlreiz nospiediet un trīs sekundes turiet nospiestas abas skaļuma pogas."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar diviem pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar trim pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Palielinājums"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vai pārslēgt uz tālruņa mikrofonu?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vai pārslēgt uz dzirdes aparāta mikrofonu?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Varat pārslēgt, lai iegūtu labāku skaņu vai ja dzirdes aparāta akumulatora uzlādes līmenis ir zems. Mikrofons tiek pārslēgts tikai zvana laikā."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Varat izmantot dzirdes aparāta mikrofonu zvaniem brīvroku režīmā. Mikrofons tiek pārslēgts tikai zvana laikā."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Pārslēgt"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Iestatījumi"</string> <string name="user_switched" msgid="7249833311585228097">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Notiek lietotāja <xliff:g id="NAME">%1$s</xliff:g> atteikšanās…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Drošības nolūkos lietotnes saturs kopīgotajā ekrānā ir paslēpts"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automātiski izveidots savienojums ar satelītu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Varat sūtīt un saņemt ziņojumus bez mobilā vai Wi-Fi tīkla."</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Vai izmantot satelīta ziņojumapmaiņu?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Sūtiet un saņemiet ziņojumus bez mobilā vai Wi‑Fi tīkla."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index c10b1ef78361..1c9e022ca3aa 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилната мрежа е недостапна"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сменете ја претпочитаната мрежа. Допрете за промена."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Итните повици се недостапни"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Не прикажувај повторно"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"За итните повици е потребна мобилна мрежа"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Предупредувања"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Проследување повик"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Известувања на мрежа"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Има достапна мрежа"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-статус"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Време и временски зони"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Предупредувања од администраторот за интернет"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Предупредувања"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Демонстрација за малопродажба"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Апликацијата работи"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликации што ја трошат батеријата"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Зголемување"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Слушен апарат"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Користење на пристапноста"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Екран"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерија"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Преземете апликација"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Вметната е нова SIM-картичка"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Допрете за да поставите"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Вашата временска зона се промени"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Во моментов сте во <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Постави време"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Постави датум"</string> <string name="date_time_set" msgid="4603445265164486816">"Постави"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим со една рака"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнително затемнување"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни помагала"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Не е поврзано"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Поврзано"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Се вчитува"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ослободете ги копчињата за јачина на звукот. Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од 3 секунди за да вклучите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 2 прста од долниот дел на екранот и брзо отпуштете."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 3 прста од долниот дел на екранот и брзо отпуштете."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Да се префрли на микрофонот на телефонот?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Да се префрли на микрофонот на слушното помагало?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"За подобар звук или ако е слаба батеријата на вашето слушно помагало. Ова го префрла вашиот микрофон само за време на повикот."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Може да го користите вашиот микрофон на слушното помагало за повикување без користење раце. Ова го префрла вашиот микрофон само за време на повикот."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Префрли"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Поставки"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Од безбедносни причини, содржините на апликацијата се скриени од споделувањето екран"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Поврзано со сателит автоматски"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Може да испраќате и примате пораки без мобилна или Wi-Fi мрежа"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Да се користи „Сателитска размена на пораки“?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Испраќајте и примајте пораки без мобилна или Wi-Fi мрежа"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отворете ја Messages"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 3eef4930796f..85dd3362990c 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"മൊബൈൽ നെറ്റ്വർക്കിലേക്ക് കണക്റ്റ് ചെയ്യാനാവുന്നില്ല"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"തിരഞ്ഞെടുത്ത നെറ്റ്വർക്ക് മാറ്റുന്നത് പരീക്ഷിക്കുക. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"എമർജൻസി കോളിംഗ് ലഭ്യമല്ല"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"വീണ്ടും കാണിക്കരുത്"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"എമർജൻസി കോളുകൾ ചെയ്യാൻ ഒരു മൊബൈൽ നെറ്റ്വർക്ക് ആവശ്യമാണ്"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"അലേർട്ടുകൾ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"കോൾ ഫോർവേഡിംഗ്"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"നെറ്റ്വർക്ക് അലേർട്ടുകൾ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"നെറ്റ്വർക്ക് ലഭ്യമല്ല"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN നില"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"സമയവും സമയമേഖലകളും"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"നിങ്ങളുടെ ഐടി അഡ്മിനിൽ നിന്നുള്ള മുന്നറിയിപ്പുകൾ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"അലേർട്ടുകൾ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"റീട്ടെയിൽ ഡെമോ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ആപ്പ് പ്രവർത്തിക്കുന്നു"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ആപ്പുകൾ ബാറ്ററി ഉപയോഗിക്കുന്നു"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"മാഗ്നിഫിക്കേഷൻ"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"കേൾവിക്കുള്ള ഉപകരണം"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ഉപയോഗസഹായി ഉപയോഗം"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ഡിസ്പ്ലേ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബാറ്ററി ഉപയോഗിക്കുന്നു"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ആപ്പ് ഡൗൺലോഡ് ചെയ്യുക"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"പുതിയ സിം ഇട്ടു"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ഇത് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"നിങ്ങളുടെ സമയമേഖല മാറി"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"നിങ്ങൾ ഇപ്പോൾ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) എന്നതിൽ ആണ്"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"സമയം സജ്ജീകരിക്കുക"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ദിവസം സജ്ജീകരിക്കുക"</string> <string name="date_time_set" msgid="4603445265164486816">"സജ്ജമാക്കുക"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ഒറ്റക്കൈ മോഡ്"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"കൂടുതൽ ഡിം ചെയ്യൽ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ശ്രവണ ഉപകരണങ്ങൾ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"വിച്ഛേദിച്ചു"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"കണക്റ്റ് ചെയ്തു"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"സജീവം"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ലോഡ് ചെയ്യുന്നു"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"വോളിയം കീകൾ വിടുക. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കാൻ, രണ്ട് വോളിയം കീകളും വീണ്ടും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 2 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്ത് പെട്ടെന്ന് വിടുക."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 3 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്ത് പെട്ടെന്ന് വിടുക."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"മാഗ്നിഫിക്കേഷൻ"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ഫോൺ മൈക്കിലേക്ക് മാറണോ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ശ്രവണ സഹായി മൈക്കിലേക്ക് മാറണോ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"മികച്ച ശബ്ദത്തിന് അല്ലെങ്കിൽ നിങ്ങളുടെ ശ്രവണ സഹായിയുടെ ബാറ്ററി കുറവാണെങ്കിൽ. ഇത് കോൾ സമയത്ത് മാത്രം നിങ്ങളുടെ മൈക്ക് മാറ്റുന്നു."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ഹാൻഡ്സ്-ഫ്രീ ആയി കോൾ ചെയ്യാൻ നിങ്ങളുടെ ശ്രവണ സഹായി മൈക്രോഫോൺ ഉപയോഗിക്കാം. ഇത് കോൾ സമയത്ത് മാത്രം നിങ്ങളുടെ മൈക്ക് മാറ്റുന്നു."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"മാറുക"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ക്രമീകരണം"</string> <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> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് ആപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"നിങ്ങൾക്ക് സാറ്റലൈറ്റ് വഴി സന്ദേശങ്ങൾ അയയ്ക്കാനും സ്വീകരിക്കാനും പരിമിതമായ ഡാറ്റ ഉപയോഗിക്കാനും കഴിയും"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"സാറ്റലൈറ്റ് സന്ദേശമയയ്ക്കൽ ഉപയോഗിക്കണോ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"മൊബൈൽ അല്ലെങ്കിൽ വൈഫൈ നെറ്റ്വർക്ക് ഇല്ലാതെ സന്ദേശങ്ങൾ അയയ്ക്കുകയും സ്വീകരിക്കുകയും ചെയ്യുക"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index f81cff89ca21..e70a95ce77d2 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Хөдөлгөөнт холбооны сүлжээнд холбогдох боломжгүй байна"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сонгосон сүлжээг өөрчлөхөөр оролдоно уу. Өөрчлөхийн тулд товшино уу."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Яаралтай дуудлага хийх боломжгүй"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Дахиж бүү харуул"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Яаралтай дуудлагуудад хөдөлгөөнт холбооны сүлжээ шаардлагатай"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сануулга"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Дуудлага шилжүүлэх"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Сүлжээний сануулга"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Сүлжээ боломжтой"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN төлөв"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Цаг, цагийн бүс"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Таны IT админаас илгээсэн сэрэмжлүүлэг"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Сануулга"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Жижиглэнгийн жишээ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Апп ажиллаж байна"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апп батарей ашиглаж байна"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Томруулах"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Сонсголын төхөөрөмж"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Хандалтын ашиглалт"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Дэлгэц"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> батарей ашиглаж байна"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Апп татаж авах"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Шинэ SIM-г оруулсан"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Үүнийг тохируулахын тулд дарна уу"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Таны цагийн бүс өөрчлөгдсөн"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Та одоо <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)-д байна"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Цагийн тохируулах"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Огноо оруулах"</string> <string name="date_time_set" msgid="4603445265164486816">"Тохируулах"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Нэг гарын горим"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Хэт бүүдгэр"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Сонсголын төхөөрөмжүүд"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Салсан"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Холбогдсон"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Идэвхтэй"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Ачаалж байна"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дууны түвшний товчнуудыг суллана уу. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаахын тулд дууны түвшний 2 товчийг зэрэг 3 секундийн турш удаан дарна уу."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 2 хуруугаараа дээш шудраад, түргэн суллана уу."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 3 хуруугаараа дээш шудраад, түргэн суллана уу."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Утасны микрофон руу сэлгэх үү?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Сонсголын төхөөрөмжийн микрофон руу сэлгэх үү?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дуу чимээг сайжруулахын тулд эсвэл таны сонсголын төхөөрөмжийн батарей бага бол. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Та гараас хамаарахгүй дуудлагад сонсголын төхөөрөмжийнхөө микрофоныг ашиглаж болно. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Сэлгэх"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Тохиргоо"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын үүднээс аппын контентыг дэлгэц хуваалцахаас нуусан"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Хиймэл дагуулд автоматаар холбогдсон"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Хиймэл дагуулаар дамжин мессеж бичихийг ашиглах уу?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Хөдөлгөөнт холбооны эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 98fedef134b9..cbe6b979d1d8 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क उपलब्ध नाही"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"प्राधान्य दिलेले नेटवर्क बदलण्याचा प्रयत्न करा. बदलण्यासाठी टॅप करा."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आणीबाणी कॉलिंग अनुपलब्ध"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"पुन्हा दाखवू नका"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आणीबाणी कॉलसाठी मोबाइल नेटवर्क आवश्यक आहे"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्ट"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल फॉरवर्डिंग"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"नेटवर्क सूचना"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"नेटवर्क उपलब्ध"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN स्थिती"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"वेळ आणि टाइम झोन"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"तुमच्या IT ॲडमिनकडून आलेल्या सूचना"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"सूचना"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"रीटेल डेमो"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP चालत आहे"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"बॅटरी लवकर संपवणारी अॅप्स"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"मॅग्निफिकेशन"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"श्रवणयंत्र"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"अॅक्सेसिबिलिटी वापर"</string> <string name="notification_channel_display" msgid="6905032605735615090">"डिस्प्ले"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅटरी वापरत आहे"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"अॅप डाउनलोड करा"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"नवीन सिम घाला"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ते सेट करण्यासाठी टॅप करा"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"तुमचा टाइम झोन बदलला आहे"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"आता तुम्ही <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) मध्ये आहात."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"वेळ सेट करा"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"तारीख सेट करा"</string> <string name="date_time_set" msgid="4603445265164486816">"सेट करा"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एकहाती मोड"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"आणखी डिम"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्रे"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिस्कनेक्ट केले आहे"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट केले आहे"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"अॅक्टिव्ह"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"लोड करत आहे"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. २ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. ३ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"मॅग्निफिकेशन"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"फोनच्या माइकवर स्विच करायचे आहे का?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"श्रवणयंत्राच्या माइकवर स्विच करायचे आहे का?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"चांगल्या आवाजासाठी किंवा तुमच्या श्रवणयंत्राची बॅटरी कमी असल्यास. यामुळे कॉलदरम्यान फक्त तुमचा माइक स्विच केला जातो."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"हँड्स-फ्री कॉलिंगसाठी तुम्ही तुमच्या श्रवणयंत्राचा मायक्रोफोन वापरू शकता. यामुळे कॉलदरम्यान फक्त तुमचा माइक स्विच केला जातो."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करा"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग्ज"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रीन शेअर करताना सुरक्षेसाठी अॅपमधील आशय लपवला आहे"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"उपग्रहाशी आपोआप कनेक्ट केलेले आहे"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"तुम्ही मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवू आणि मिळवू शकता"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"सॅटेलाइट मेसेजिंग वापरायचे आहे का?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवणे आणि मिळवणे"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 2ce54d0ffc39..5cb9defbcd3e 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat mencapai rangkaian mudah alih"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Cuba tukar rangkaian pilihan. Ketik untuk menukar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan kecemasan tidak tersedia"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Jangan Tunjukkan Lagi"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Rangkaian mudah alih diperlukan untuk membuat panggilan kecemasan"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Makluman"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Pemajuan panggilan"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Makluman rangkaian"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rangkaian tersedia"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Masa dan zon waktu"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Makluman daripada pentadbir IT anda"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Makluman"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Tunjuk cara runcit"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Apl berjalan"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apl yang menggunakan bateri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pembesaran"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Peranti pendengaran"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Penggunaan kebolehaksesan"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Paparan"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan bateri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Muat turun apl"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM baharu dimasukkan"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Ketik untuk menyediakannya"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Zon waktu anda berubah"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Kini anda berada dalam <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Tetapkan masa"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Tetapkan tarikh"</string> <string name="date_time_set" msgid="4603445265164486816">"Tetapkan"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Mod sebelah tangan"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Amat malap"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Peranti pendengaran"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Diputuskan sambungan"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Disambungkan"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktif"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Memuatkan"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan kekunci kelantangan. Untuk menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, sila tekan dan tahan kedua-dua kekunci kelantangan sekali lagi selama 3 saat."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 2 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 3 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Tukar kepada mikrofon telefon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Tukar kepada mikrofon alat bantu pendengaran?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Untuk mendapatkan bunyi yang lebih baik atau jika bateri alat bantu pendengaran anda lemah. Tindakan ini hanya menukar mikrofon anda semasa panggilan."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Anda boleh menggunakan mikrofon alat bantu pendengaran anda untuk membuat panggilan bebas tangan. Tindakan ini hanya menukar mikrofon anda semasa panggilan."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Tukar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Tetapan"</string> <string name="user_switched" msgid="7249833311585228097">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Beralih kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Log keluar daripada <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Kandungan apl disembunyikan daripada perkongsian skrin untuk keselamatan"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Disambungkan secara automatik kepada satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda boleh menghantar dan menerima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"Anda boleh menghantar dan menerima mesej serta menggunakan data terhad melalui satelit"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Gunakan pemesejan satelit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Hantar dan terima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 3e0187a225a0..432f7f9c6aa0 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"မိုဘိုင်းကွန်ရက် လိုင်းမရပါ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ဦးစားပေးကွန်ရက်သို့ ပြောင်းကြည့်ပါ။ ပြောင်းရန် တို့ပါ။"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"အရေးပေါ်ခေါ်ဆိုမှု မရနိုင်ပါ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ထပ်မပြပါနှင့်"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"အရေးပေါ်ဖုန်းခေါ်ရန် မိုဘိုင်းကွန်ရက် လိုအပ်သည်"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"သတိပေးချက်များ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ကွန်ရက် သတိပေးချက်များ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ကွန်ရက်ချိတ်ဆက်မှု ရရှိနိုင်ပါသည်"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN အခြေအနေ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"အချိန်နှင့် ဒေသစံတော်ချိန်များ"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"သင်၏ IT စီမံခန့်ခွဲသူထံမှ သတိပေးချက်များ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"သတိပေးချက်များ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"လက်လီအရောင်းဆိုင် သရုပ်ပြမှု"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"APP လုပ်ဆောင်နေသည်"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"အက်ပ်များက ဘက်ထရီကုန်စေသည်"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ချဲ့ခြင်း"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"နားကြားကိရိယာ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"အများသုံးစွဲနိုင်မှုကို အသုံးပြုမှု"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ဖန်သားပြင်"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> က ဘက်ထရီကို အသုံးပြုနေသည်"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"အက်ပ် ဒေါင်းလုဒ်လုပ်ရန်"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM အသစ်ထည့်သွင်းလိုက်ပါသည်"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"၎င်းကိုတပ်ဆင်ရန် တို့ပါ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"သင်၏ဒေသစံတော်ချိန် ပြောင်းသွားပါပြီ"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"သင်သည် ယခု <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) တွင် ရှိနေသည်"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"အချိန်သတ်မှတ်ရန်"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ရက်စွဲ အတည်ပြုရန်"</string> <string name="date_time_set" msgid="4603445265164486816">"သတ်မှတ်ရန်"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"လက်တစ်ဖက်သုံးမုဒ်"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ပိုမှိန်ခြင်း"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"နားကြားကိရိယာ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ချိတ်ဆက်မထားပါ"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"ချိတ်ဆက်ထားသည်"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"သုံးနေသည်"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ဖွင့်နေသည်"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"အသံထိန်းခလုတ်များကို လွှတ်လိုက်ပါ။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်ရန် အသံထိန်းခလုတ်နှစ်ခုစလုံးကို ၃ စက္ကန့်ကြာအောင် ထပ်နှိပ်ပါ။"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၃ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ချဲ့ခြင်း"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ဖုန်း၏မိုက်သို့ ပြောင်းမလား။"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"နားကြားကိရိယာ၏မိုက်သို့ ပြောင်းမလား။"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"အသံပိုကောင်းစေရန် (သို့) နားကြားကိရိယာ၏ ဘက်ထရီ နည်းနေပါက။ ခေါ်ဆိုနေစဉ်သာ သင့်မိုက်ကို ပြောင်းပေးသည်။"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"လက်လွတ်ခေါ်ဆိုခြင်းအတွက် နားကြားကိရိယာ၏ မိုက်ခရိုဖုန်းကို သုံးနိုင်သည်။ ခေါ်ဆိုနေစဉ်သာ သင့်မိုက်ကို ပြောင်းပေးသည်။"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ပြောင်းရန်"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ဆက်တင်များ"</string> <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> @@ -1949,13 +1954,13 @@ <string name="data_saver_enable_title" msgid="7080620065745260137">"ဒေတာချွေတာမှုစနစ် ဖွင့်မလား။"</string> <string name="data_saver_enable_button" msgid="4399405762586419726">"ဖွင့်ရန်"</string> <string name="zen_mode_duration_minutes_summary" msgid="4555514757230849789">"{count,plural, =1{တစ်မိနစ်ကြာ ({formattedTime} အထိ)}other{# မိနစ်ကြာ ({formattedTime} အထိ)}}"</string> - <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{1 မိနစ်ကြာ ({formattedTime} အထိ)}other{# မိနစ်ကြာ ({formattedTime} အထိ)}}"</string> - <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{1 နာရီကြာ ({formattedTime} အထိ)}other{# နာရီကြာ ({formattedTime} အထိ)}}"</string> - <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{1 နာရီကြာ ({formattedTime} အထိ)}other{# နာရီကြာ ({formattedTime} အထိ)}}"</string> + <string name="zen_mode_duration_minutes_summary_short" msgid="1187553788355486950">"{count,plural, =1{၁ မိနစ်ကြာ ({formattedTime} အထိ)}other{# မိနစ်ကြာ ({formattedTime} အထိ)}}"</string> + <string name="zen_mode_duration_hours_summary" msgid="3866333100793277211">"{count,plural, =1{၁ နာရီကြာ ({formattedTime} အထိ)}other{# နာရီကြာ ({formattedTime} အထိ)}}"</string> + <string name="zen_mode_duration_hours_summary_short" msgid="687919813833347945">"{count,plural, =1{၁ နာရီကြာ ({formattedTime} အထိ)}other{# နာရီကြာ ({formattedTime} အထိ)}}"</string> <string name="zen_mode_duration_minutes" msgid="2340007982276569054">"{count,plural, =1{တစ်မိနစ်ကြာ}other{# မိနစ်ကြာ}}"</string> <string name="zen_mode_duration_minutes_short" msgid="2435756450204526554">"{count,plural, =1{1 မိနစ်ကြာ}other{# မိနစ်ကြာ}}"</string> - <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{1 နာရီကြာ}other{# နာရီကြာ}}"</string> - <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1 နာရီကြာ}other{# နာရီကြာ}}"</string> + <string name="zen_mode_duration_hours" msgid="7841806065034711849">"{count,plural, =1{၁ နာရီကြာ}other{# နာရီကြာ}}"</string> + <string name="zen_mode_duration_hours_short" msgid="3666949653933099065">"{count,plural, =1{1၁ နာရီကြာ}other{# နာရီကြာ}}"</string> <string name="zen_mode_until_next_day" msgid="1403042784161725038">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> အထိ"</string> <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string> <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> အထိ (လာမည့် နှိုးစက်)"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"လုံခြုံရေးအတွက် အက်ပ်အကြောင်းအရာကို ဖန်သားပြင် မျှဝေခြင်းတွင် ဖျောက်ထားသည်"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ဂြိုဟ်တုနှင့် အလိုအလျောက် ချိတ်ဆက်ထားသည်"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ဂြိုဟ်တုမှတစ်ဆင့် မက်ဆေ့ဂျ်ပို့ခြင်း သုံးမလား။"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များ ပို့နိုင်၊ လက်ခံနိုင်သည်"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index d21296d28696..c80a9605fcde 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Får ikke kontakt med mobilnettverket"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv å endre foretrukket nettverk. Trykk for å endre."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nødanrop er utilgjengelig"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ikke vis dette igjen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Du må være koblet til et mobilnettverk for å utføre nødanrop"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Varsler"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderekobling"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Nettverksvarsler"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Nettverk er tilgjengelig"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Tid og tidssoner"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Varsler fra IT-administratoren din"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Varsler"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Butikkdemo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App kjører"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apper bruker batteri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Forstørring"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Høreapparat"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Bruk av Tilgjengelighet"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skjerm"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker batteri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Last ned appen"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Et nytt SIM-kort er satt inn"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Konfigurer"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Tidssonen er endret"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Nå er du i <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Angi tidspunkt"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Angi dato"</string> <string name="date_time_set" msgid="4603445265164486816">"Lagre"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhåndsmodus"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra dimmet"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Frakoblet"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Tilkoblet"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Laster inn"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slipp opp volumtastene. For å slå på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, trykk og hold på begge volumtastene igjen i 3 sekunder."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 2 fingre fra nederst på skjermen, og slipp raskt opp."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 3 fingre fra nederst på skjermen, og slipp raskt opp."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørring"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vil du bytte til mikrofonen i telefonen?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vil du bytte til mikrofonen i høreapparatet?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For bedre lyd eller hvis høreapparatet har lite batteri. Dette fører bare til at mikrofonen byttes under samtalen."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan bruke mikrofonen i høreapparatet til å ringe håndfritt. Dette fører bare til at mikrofonen byttes under samtalen."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Bytt"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Innstillinger"</string> <string name="user_switched" msgid="7249833311585228097">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Logger av <xliff:g id="NAME">%1$s</xliff:g> …"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Av sikkerhetsgrunner er appinnholdet skjult for skjermdelingen"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisk tilkoblet satellitt"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og motta meldinger uten mobil- eller wifi-nettverk"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Vil du bruke satellittmeldinger?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Send og motta meldinger uten mobil- eller wifi-nettverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index c524a4847c69..bf7bbaf872be 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्कमाथि पहुँच राख्न सकिएन"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"रुचाइएको नेटवर्क परिवर्तन गरी हेर्नुहोस्। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपत्कालीन कल सेवा अनुपलब्ध छ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"फेरि नदेखाउनुहोस्"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आपत्कालीन कलहरू गर्न मोबाइल नेटवर्क चाहिन्छ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्टहरू"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"कल फर्वार्ड गर्ने सेवा"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"नेटवर्कका अलर्टहरू"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"नेटवर्क उपलब्ध छ"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN को स्थिति"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"समय र प्रामाणिक समय"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"तपाईंको IT प्रशासकबाट प्राप्त सतर्कताहरू"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"अलर्टहरू"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"खुद्रा बिक्री सम्बन्धी डेमो"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"एप चलिरहेको छ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"एपहरूले ब्याट्री खपत गर्दै छन्"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"जुम इन गर्ने सुविधा"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"श्रवण यन्त्र"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"सर्वसुलभतासम्बन्धी सेवाहरूको प्रयोग"</string> <string name="notification_channel_display" msgid="6905032605735615090">"डिस्प्ले"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले ब्याट्री प्रयोग गर्दै छ"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"एप डाउनलोड गर्नुहोस्"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"नयाँ SIM घुसाइयो"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"यसलाई सेटअप गर्न ट्याप गर्नुहोस्"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"तपाईंको प्रामाणिक समय परिवर्तन गरिएको छ"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"तपाईं अहिले <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) मा हुनुहुन्छ"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"समय मिलाउनुहोस्"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"मिति मिलाउनुहोस्"</string> <string name="date_time_set" msgid="4603445265164486816">"सेट गर्नुहोस्"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एक हाते मोड"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"अझै मधुरो"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"हियरिङ डिभाइसहरू"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"डिस्कनेक्ट गरिएको"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"कनेक्ट गरिएको"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"सक्रिय"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"लोड हुँदै छ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। २ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"फोनको माइक प्रयोग गर्ने हो?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"श्रवण यन्त्रको माइक प्रयोग गर्ने हो?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"अझ राम्रो आवाज सुनाउन वा तपाईंको श्रवण यन्त्रको ब्याट्री कम भएका खण्डमा। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो श्रवण यन्त्रको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"बदल्नुहोस्"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिङ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"स्क्रिन सेयर गर्दा सुरक्षाका लागि एपमा भएको सामग्री लुकाइएको छ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"स्याटलाइटमा स्वतः कनेक्ट गरियो"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"तपाईं मोबाइल वा Wi-Fi नेटवर्कविनै म्यासेज पठाउन र प्राप्त गर्न सक्नुहुन्छ"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"स्याटलाइटमार्फत म्यासेज पठाउने सुविधा प्रयोग गर्ने हो?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"मोबाइल वा Wi-Fi नेटवर्कविनै म्यासेजहरू पठाउनुहोस् र प्राप्त गर्नुहोस्"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages खोल्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 609d642a5672..695a706dcdb4 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan mobiel netwerk niet bereiken"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer een ander voorkeursnetwerk. Tik om te wijzigen."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepen niet beschikbaar"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Niet meer tonen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Voor noodoproepen is een mobiel netwerk vereist"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Meldingen"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Gesprek doorschakelen"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Netwerkmeldingen"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Netwerk beschikbaar"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Tijd en tijdzones"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Meldingen van je IT-team"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Meldingen"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo voor de detailhandel"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App actief"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps die de batterij gebruiken"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Vergroting"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hoortoestel"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Toegankelijkheidsgebruik"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Scherm"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt de batterij"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"App downloaden"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nieuwe simkaart geplaatst"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tik om dit in te stellen"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Je tijdzone is gewijzigd"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Je bent nu in <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Tijd instellen"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Datum instellen"</string> <string name="date_time_set" msgid="4603445265164486816">"Instellen"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Bediening met 1 hand"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dimmen"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hoortoestellen"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Verbinding verbroken"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Verbonden"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Actief"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Laden"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Laat de volumeknoppen los. Als je <xliff:g id="SERVICE_NAME">%1$s</xliff:g> wilt aanzetten, houd je beide volumeknoppen weer 3 seconden ingedrukt."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 2 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 3 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Wisselen naar microfoon van telefoon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Wisselen naar microfoon van hoortoestel?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Voor beter geluid of als de batterij van je hoortoestel bijna leeg is. Hiermee wordt de microfoon alleen gewisseld tijdens het gesprek."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Je kunt de microfoon van je hoortoestel gebruiken om handsfree te bellen. Hiermee wordt de microfoon alleen gewisseld tijdens het gesprek."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Wisselen"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Instellingen"</string> <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <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> uitloggen…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Vanwege beveiligingsrisico\'s is app-content verborgen voor scherm delen"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Satellietberichten gebruiken?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Stuur en krijg berichten zonder mobiel of wifi-netwerk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 51c4e3143586..de95a033ec20 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ମୋବାଇଲ୍ ନେଟ୍ୱର୍କ ମିଳୁନାହିଁ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ନିଜ ପସନ୍ଦର ନେଟ୍ୱର୍କକୁ ଯିବାପାଇଁ ଚେଷ୍ଟା କରନ୍ତୁ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ଜରୁରୀକାଳୀନ କଲ୍ ଉପଲବ୍ଧ ନାହିଁ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ଜରୁରୀକାଳୀନ କଲ କରିବା ପାଇଁ ଏକ ମୋବାଇଲ ନେଟୱାର୍କ ଆବଶ୍ୟକ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ଆଲର୍ଟ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"କଲ୍ ଫରୱାର୍ଡିଂ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ନେଟୱର୍କ ଅଲର୍ଟ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ନେଟ୍ୱର୍କ ଉପଲବ୍ଧ ଅଛି"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN ସ୍ଥିତି"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ସମୟ ଏବଂ ଟାଇମ ଜୋନ"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ଆପଣଙ୍କର ଆଇଟି ଆଡ୍ମିନ୍ଙ୍କ ଠାରୁ ଆଲର୍ଟ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ଆଲର୍ଟ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"ରିଟେଲ୍ ଡେମୋ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ଆପ୍ ଚାଲୁଛି"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ଆପ୍ଗୁଡ଼ିକ ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କରିଥା\'ନ୍ତି"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ମେଗ୍ନିଫିକେସନ"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"ଶ୍ରବଣ ଡିଭାଇସ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ଆକ୍ସେସିବିଲିଟୀ ବ୍ୟବହାର"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ଡିସପ୍ଲେ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରୁଛି"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ଆପ୍ ଡାଉନଲୋଡ କରନ୍ତୁ"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ନୂଆ SIM କାର୍ଡ ଭର୍ତ୍ତି କରାଗଲା"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ଏହା ସେଟଅପ୍ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"ଆପଣଙ୍କର ଟାଇମ ଜୋନ ବଦଳିଛି"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ଆପଣ ବର୍ତ୍ତମାନ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)ରେ ଅଛନ୍ତି"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ସମୟ ସେଟ୍ କରନ୍ତୁ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ତାରିଖ ସେଟ୍ କରନ୍ତୁ"</string> <string name="date_time_set" msgid="4603445265164486816">"ସେଟ୍ କରନ୍ତୁ"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ଏକ-ହାତ ମୋଡ୍"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ଅତ୍ୟଧିକ ଡିମ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ଶ୍ରବଣ ଡିଭାଇସଗୁଡ଼ିକ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ଡିସକନେକ୍ଟ କରାଯାଇଛି"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"କନେକ୍ଟ କରାଯାଇଛି"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ସକ୍ରିୟ"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ଲୋଡ ହେଉଛି"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ଭଲ୍ୟୁମ କୀ\'ଗୁଡ଼ିକୁ ରିଲିଜ କରନ୍ତୁ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g>କୁ ଚାଲୁ କରିବା ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ କୀ\'କୁ ପୁଣି 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇ ଧରି ରଖନ୍ତୁ।"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 2 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 3 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ଫୋନ ମାଇକକୁ ସୁଇଚ କରିବେ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକକୁ ସୁଇଚ କରିବେ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ଭଲ ସାଉଣ୍ଡ ପାଇଁ କିମ୍ବା ଯଦି ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ବ୍ୟାଟେରୀ କମ ଥିଲେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକ ସୁଇଚ କରିଥାଏ।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ହେଣ୍ଡସ-ଫ୍ରି କଲିଂ ପାଇଁ ଆପଣ ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକ୍ରୋଫୋନ ବ୍ୟବହାର କରିପାରିବେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକ ସୁଇଚ କରିଥାଏ।"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ସ୍ୱିଚ କରନ୍ତୁ"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ସେଟିଂସ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ସୁରକ୍ଷା ପାଇଁ ସ୍କ୍ରିନ ସେୟାରରୁ ଆପ ବିଷୟବସ୍ତୁକୁ ଲୁଚାଯାଇଛି"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ସାଟେଲାଇଟ ସହ ସ୍ୱତଃ କନେକ୍ଟ ହୋଇଛି"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ଆପଣ ମେସେଜ ପଠାଇପାରିବେ ଏବଂ ପାଇପାରିବେ"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ସେଟେଲାଇଟ ମେସେଜିଂକୁ ବ୍ୟବହାର କରିବେ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ମେସେଜ ପଠାନ୍ତୁ ଏବଂ ପାଆନ୍ତୁ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 12f4e901ce07..4d4b10bb25db 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਨੂੰ ਬਦਲ ਕੇ ਦੇਖੋ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਿੰਗ ਉਪਲਬਧ ਨਹੀਂ"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਲਈ ਕਿਸੇ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ਅਲਰਟ"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ਨੈੱਟਵਰਕ ਅਲਰਟ"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ਨੈੱਟਵਰਕ ਉਪਲਬਧ ਹੈ"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN ਅਵਸਥਾ"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"ਸਮਾਂ ਅਤੇ ਸਮਾਂ ਖੇਤਰ"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅਲਰਟ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ਅਲਰਟ"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ਚੱਲ ਰਹੀ ਐਪ"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰਨ ਵਾਲੀਆਂ ਐਪਾਂ"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"ਸੁਣਨ ਵਾਲਾ ਡੀਵਾਈਸ"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ਪਹੁੰਚਯੋਗਤਾ ਵਰਤੋਂ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ਡਿਸਪਲੇ"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ਐਪ ਡਾਊਨਲੋਡ ਕਰੋ"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ਨਵੀਂ SIM ਦਾਖਲ ਕੀਤੀ ਗਈ"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"ਇਸ ਨੂੰ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"ਤੁਹਾਡਾ ਸਮਾਂ ਖੇਤਰ ਬਦਲ ਗਿਆ ਹੈ"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ਹੁਣ ਤੁਸੀਂ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ਵਿੱਚ ਹੋ"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ਸਮਾਂ ਸੈੱਟ ਕਰੋ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ਤਾਰੀਖ ਸੈੱਟ ਕਰੋ"</string> <string name="date_time_set" msgid="4603445265164486816">"ਸੈੱਟ ਕਰੋ"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ਇੱਕ ਹੱਥ ਮੋਡ"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ਜ਼ਿਆਦਾ ਘੱਟ ਚਮਕ"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ਸੁਣਨ ਵਾਲੇ ਡੀਵਾਈਸ"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"ਕਨੈਕਟ ਹੈ"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ਕਿਰਿਆਸ਼ੀਲ"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ ਛੱਡੋ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰਨ ਲਈ, ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦੁਬਾਰਾ ਦਬਾਈ ਰੱਖੋ।"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 2 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 3 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ਕੀ ਫ਼ੋਨ ਦੇ ਮਾਈਕ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ਕੀ ਸੁਣਨ ਦੇ ਸਾਧਨ ਦੇ ਮਾਈਕ \'ਤੇ ਸਵਿੱਚ ਕਰਨਾ ਹੈ?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ਬਿਹਤਰ ਧੁਨੀ ਲਈ ਜਾਂ ਜੇ ਤੁਹਾਡੇ ਸੁਣਨ ਦੇ ਸਾਧਨ ਦੀ ਬੈਟਰੀ ਘੱਟ ਹੈ। ਇਹ ਸਿਰਫ਼ ਕਾਲ ਦੌਰਾਨ ਹੀ ਤੁਹਾਡੇ ਮਾਈਕ ਨੂੰ ਸਵਿੱਚ ਕਰਦਾ ਹੈ।"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ਤੁਸੀਂ ਹੱਥ-ਰਹਿਤ ਕਾਲਿੰਗ ਲਈ ਆਪਣੇ ਸੁਣਨ ਦੇ ਸਾਧਨ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰ ਸਕਦੇ ਹੋ। ਇਹ ਸਿਰਫ਼ ਕਾਲ ਦੌਰਾਨ ਹੀ ਤੁਹਾਡੇ ਮਾਈਕ ਨੂੰ ਸਵਿੱਚ ਕਰਦਾ ਹੈ।"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ਸਵਿੱਚ ਕਰੋ"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ਸੈਟਿੰਗਾਂ"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ਐਪ ਸਮੱਗਰੀ ਨੂੰ ਸੁਰੱਖਿਆ ਲਈ ਸਕ੍ਰੀਨ ਸਾਂਝਾਕਰਨ ਤੋਂ ਲੁਕਾਇਆ ਗਿਆ ਹੈ"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"ਸੈਟੇਲਾਈਟ ਨਾਲ ਸਵੈ-ਕਨੈਕਟ ਹੋਇਆ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ਤੁਸੀਂ ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ਕੀ ਸੈਟੇਲਾਈਟ ਸੁਨੇਹੇ ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਹੈ?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰੋ"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 113ffa37084e..810aa325e48a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Brak zasięgu sieci komórkowej"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Spróbuj zmienić preferowaną sieć. Kliknij, by zmienić."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Połączenia alarmowe są niedostępne"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Nie pokazuj ponownie"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Połączenia alarmowe wymagają sieci komórkowej"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerty"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Przekierowanie połączeń"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alerty dotyczące sieci"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Sieć dostępna"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stan sieci VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Godzina i strefy czasowe"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerty od administratora IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerty"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Tryb demo dla sklepów"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Działa aplikacja"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacje zużywające baterię"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Powiększenie"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Urządzenie słuchowe"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Użycie ułatwień dostępu"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Wyświetlacz"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> zużywa baterię"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Pobierz aplikację"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Włożono nową kartę SIM"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Kliknij, by skonfigurować"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Zmieniła się Twoja strefa czasowa"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Jesteś teraz w strefie <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Ustaw godzinę"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Ustaw datę"</string> <string name="date_time_set" msgid="4603445265164486816">"Ustaw"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tryb jednej ręki"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Dodatkowe przyciemnienie"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Urządzenia słuchowe"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Rozłączone"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Połączone"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktywne"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Wczytuję"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Zwolnij przyciski głośności. Aby włączyć usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, naciśnij i przytrzymaj oba przyciski głośności przez 3 sekundy."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 2 palcami z dołu ekranu i szybko je unieś."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 3 palcami z dołu ekranu i szybko je unieś."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Powiększenie"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Przełączyć na mikrofon w telefonie?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Przełączyć na mikrofon w aparacie słuchowym?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Skorzystaj z tej opcji, aby uzyskać lepszy dźwięk lub jeśli kończy się bateria w aparacie słuchowym. Mikrofon zostanie przełączony tylko na czas połączenia."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Możesz używać mikrofonu w aparacie słuchowym, aby dzwonić bez użycia rąk. Mikrofon zostanie przełączony tylko na czas połączenia."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Przełącz"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ustawienia"</string> <string name="user_switched" msgid="7249833311585228097">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Wylogowuję użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2456,6 +2461,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Ze względów bezpieczeństwa zawartość aplikacji jest niewidoczna podczas udostępniania ekranu"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatycznie połączono z satelitą"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Możesz wymieniać wiadomości bez dostępu do sieci komórkowej lub Wi-Fi"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"Przez satelitę możesz wysyłać i odbierać wiadomości oraz w ograniczonym stopniu korzystać z transmisji danych"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Przesyłać wiadomości przez satelitę?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Wysyłaj i odbieraj wiadomości bez sieci komórkowej czy Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 2daa730b4a31..cc4b251c7713 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Não mostrar de novo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emergência exigem uma rede móvel"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas de rede"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rede disponível"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status de VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora e fusos horários"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas do administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstração na loja"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Aparelho auditivo"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de acessibilidade"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Tela"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Baixar o app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Seu fuso horário mudou"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Agora você está em <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Definir hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Definir data"</string> <string name="date_time_set" msgid="4603445265164486816">"Definir"</string> @@ -1779,16 +1782,12 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer ainda mais a tela"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Tela ainda mais escura"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Carregando"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Trocar para o microfone do smartphone?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Trocar para o microfone do aparelho auditivo?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para melhorar o som ou se a bateria do aparelho auditivo estiver fraca. A troca do microfone só será feita durante a ligação."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Você pode usar o microfone do aparelho auditivo para fazer ligações sem usar as mãos. A troca do microfone só será feita durante a ligação."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Trocar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configurações"</string> <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Usar mensagens via satélite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 5572de130221..af76e3f1ad03 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não é possível estabelecer ligação à rede móvel."</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Experimente alterar a rede preferida. Toque para alterar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Não mostrar novamente"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emergência requerem uma rede móvel"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Reencaminhamento de chamadas"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas da rede"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rede disponível"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Estado da VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora e fusos horários"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas do seu administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstração para retalho"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicação em execução"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão a consumir bateria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Dispositivo auditivo"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Utilização da acessibilidade"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ecrã"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a consumir bateria."</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Transferir app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo SIM inserido"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"O seu fuso horário foi alterado"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Está agora em <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Definir hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Definir data"</string> <string name="date_time_set" msgid="4603445265164486816">"Definir"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mais escuro"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desligado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Ligado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"A carregar"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, prima sem soltar ambas as teclas de volume novamente durante 3 segundos."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize com 2 dedos a partir da parte inferior do ecrã e solte rapidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize para cima com 3 dedos a partir da parte inferior do ecrã e solte rapidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Mudar para o microfone do telemóvel?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Mudar para o microfone do aparelho auditivo?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para um som melhor ou se a bateria do aparelho auditivo estiver fraca. Esta ação apenas muda o microfone durante a chamada."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pode usar o microfone do aparelho auditivo para chamadas mãos-livres. Esta ação apenas muda o microfone durante a chamada."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Mudar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Definições"</string> <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string> <string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"A terminar a sessão de <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,7 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo da app ocultado da partilha de ecrã por motivos de segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Ligação de satélite estabelecida automaticamente"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Pode enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string> + <string name="satellite_notification_summary_with_data" msgid="6486843676720429049">"Pode enviar e receber mensagens, e usar dados limitados, por satélite"</string> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Quer usar as mensagens por satélite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Envie e receba mensagens sem uma rede móvel ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 2daa730b4a31..cc4b251c7713 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Não mostrar de novo"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emergência exigem uma rede móvel"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alertas de rede"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rede disponível"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status de VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Hora e fusos horários"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alertas do administrador de TI"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertas"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstração na loja"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App em execução"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Apps que estão consumindo a bateria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ampliação"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Aparelho auditivo"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uso de acessibilidade"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Tela"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está consumindo a bateria"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Baixar o app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Seu fuso horário mudou"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Agora você está em <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Definir hora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Definir data"</string> <string name="date_time_set" msgid="4603445265164486816">"Definir"</string> @@ -1779,16 +1782,12 @@ <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string> <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string> <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string> - <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer ainda mais a tela"</string> + <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Tela ainda mais escura"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Desconectado"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectado"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Ativo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Carregando"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Trocar para o microfone do smartphone?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Trocar para o microfone do aparelho auditivo?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para melhorar o som ou se a bateria do aparelho auditivo estiver fraca. A troca do microfone só será feita durante a ligação."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Você pode usar o microfone do aparelho auditivo para fazer ligações sem usar as mãos. A troca do microfone só será feita durante a ligação."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Trocar"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Configurações"</string> <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Desconectando <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Usar mensagens via satélite?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index cf0f771b190c..25b0471347c9 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nu se poate stabili conexiunea la rețeaua mobilă"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Încearcă să schimbi rețeaua preferată. Atinge pentru a schimba."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Apelurile de urgență nu sunt disponibile"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Nu mai afișa"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Apelurile de urgență necesită o rețea mobilă"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerte"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Redirecționarea apelurilor"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Alerte privind rețeaua"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Rețea disponibilă"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stare VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ora și fusurile orare"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Alerte de la administratorul IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Alerte"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstrație comercială"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplicația rulează"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplicațiile consumă bateria"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Mărire"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Aparat auditiv"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Folosirea accesibilității"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ecran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește bateria"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Descarcă aplicația"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"S-a introdus un card SIM nou"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Atinge pentru a-l configura"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Fusul orar s-a schimbat"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Acum te afli în <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Setează ora"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Setează data"</string> <string name="date_time_set" msgid="4603445265164486816">"Setează"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modul cu o mână"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Luminozitate redusă suplimentar"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparate auditive"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Deconectat"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Conectat"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Activ"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Se încarcă"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Eliberează butoanele de volum. Pentru a activa <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, apasă lung pe ambele butoane de volum timp de trei secunde încă o dată."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu două degete din partea de jos a ecranului și ridică-le rapid."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu trei degete din partea de jos a ecranului și ridică-le rapid."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Mărire"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Comuți la microfonul telefonului?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Comuți la microfonul aparatului auditiv?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pentru un sunet mai bun sau dacă bateria aparatului auditiv este descărcată. Astfel, microfonul pornește numai în timpul apelului."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Poți folosi microfonul aparatului auditiv pentru apelarea hands-free. Astfel, microfonul pornește numai în timpul apelului."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Schimbă"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Setări"</string> <string name="user_switched" msgid="7249833311585228097">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Se deconectează utilizatorul <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conținutul aplicației este ascuns de permiterea accesului la ecran din motive de securitate"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"S-a conectat automat la satelit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Poți să trimiți și să primești mesaje fără o rețea mobilă sau Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Folosești mesajele prin satelit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Trimite și primește mesaje fără o rețea mobilă sau Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 387cd338bb9c..1efa10593edc 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильная сеть недоступна"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Нажмите, чтобы выбрать другую сеть."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстренные вызовы недоступны"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Больше не показывать"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Для экстренных вызовов нужна мобильная сеть."</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Оповещения"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресация вызовов"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Оповещения сети"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Сеть доступна"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Время и часовые пояса"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Уведомления от вашего администратора"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Уведомления"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Деморежим для магазина"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Приложение активно"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Приложения, расходующие заряд"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увеличение"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Слуховой аппарат"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Сервисы специальных возможностей"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Экран"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" расходует заряд"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Скачать приложение"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Установлена новая SIM-карта"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Нажмите, чтобы настроить."</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Ваш часовой пояс изменился"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Новый часовой пояс: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Настройка времени"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Настройка даты"</string> <string name="date_time_set" msgid="4603445265164486816">"Установить"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим управления одной рукой"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Дополнительное уменьшение яркости"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слуховые аппараты"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Отключено"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Подключено"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Загрузка…"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Отпустите кнопки громкости. Чтобы включить <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите двумя пальцами по экрану снизу вверх."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите тремя пальцами по экрану снизу вверх."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Переключиться на микрофон телефона?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Переключиться на микрофон слухового аппарата?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Вы можете использовать микрофон телефона, если вас не устраивает качество звука или если у слухового аппарата низкий заряд батареи. Микрофон будет переключен только на время звонка."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Вы можете использовать микрофон слухового аппарата, когда разговариваете по телефону. Микрофон будет переключен только на время звонка."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Переключиться"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Настройки"</string> <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> @@ -2456,6 +2461,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Для безопасности содержимое приложения при демонстрации экрана скрыто."</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматически подключено к системам спутниковой связи"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Включить спутниковый обмен сообщениями?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Отправляйте и получайте сообщения без подключения к мобильной сети или Wi-Fi."</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 9fd63e471962..57f89a230384 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ජංගම ජාලය වෙත ළඟා විය නොහැකිය"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"කැමති ජාලය වෙනස් කිරීමට උත්සාහ කරන්න. වෙනස් කිරීමට තට්ටු කරන්න."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"හදිසි ඇමතුම් ලබා ගත නොහැකිය"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"නැවතත් නොපෙන්වන්න"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"හදිසි ඇමතුම් සඳහා ජංගම ජාලයක් අවශ්ය වේ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"ඇඟවීම්"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"ඇමතුම ප්රතියොමු කිරීම"</string> @@ -303,6 +302,8 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"ජාල ඇඟවීම්"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"ජාලය ලබා ගැනීමට හැකිය"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN තත්ත්වය"</string> + <!-- no translation found for notification_channel_system_time (1660313368058030441) --> + <skip /> <string name="notification_channel_device_admin" msgid="6384932669406095506">"ඔබේ තොරතුරු තාක්ෂණ පරිපාලක වෙතින් ඇඟවීම්"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"ඇඟවීම්"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"සිල්ලර ආදර්ශනය"</string> @@ -310,6 +311,8 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"යෙදුම ධාවනය කරමින්"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"බැටරිය භාවිත කරන යෙදුම්"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"විශාලනය"</string> + <!-- no translation found for notification_channel_accessibility_hearing_device (7816963856388758952) --> + <skip /> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ප්රවේශ්යතා භාවිතය"</string> <string name="notification_channel_display" msgid="6905032605735615090">"සංදර්ශකය"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> බැටරිය භාවිත කරයි"</string> @@ -1407,6 +1410,10 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"යෙදුම බාගන්න"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"නව SIM ඇතුළු කරන්න"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"එය පිහිටුවීමට තට්ටු කරන්න"</string> + <!-- no translation found for time_zone_change_notification_title (5232503069219193218) --> + <skip /> + <!-- no translation found for time_zone_change_notification_body (6135793674904665585) --> + <skip /> <string name="time_picker_dialog_title" msgid="9053376764985220821">"වේලාව සකසන්න"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"දිනය සැකසීම"</string> <string name="date_time_set" msgid="4603445265164486816">"සකසන්න"</string> @@ -1780,14 +1787,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"තනි අත් ප්රකාරය"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"තවත් අඳුරු"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ශ්රවණ උපාංග"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"විසන්ධි විය"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"සම්බන්ධිතයි"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"සක්රිය"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"පූරණය වේ"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාත්මකයි."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාවිරහිතයි."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"හඬ පරිමා යතුරු මුදා හරින්න. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> සක්රීය කිරීමට, හඬ පරිමා යතුරු දෙකම නැවත තත්පර 3ක් ඔබා අල්ලා සිටින්න."</string> @@ -1798,6 +1801,18 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 2කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 3කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"විශාලනය"</string> + <!-- no translation found for hearing_device_switch_phone_mic_notification_title (6645178038359708836) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_title (4612074852145289569) --> + <skip /> + <!-- no translation found for hearing_device_switch_phone_mic_notification_text (1332426273666077412) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_text (8288368365767284208) --> + <skip /> + <!-- no translation found for hearing_device_notification_switch_button (3619524619430941300) --> + <skip /> + <!-- no translation found for hearing_device_notification_settings_button (6673651052880279178) --> + <skip /> <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> @@ -2454,6 +2469,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ආරක්ෂාව සඳහා යෙදුම් අන්තර්ගතය තිරය බෙදා ගැනීමෙන් සඟවා ඇත"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"චන්ද්රිකාවට ස්වයංක්රීයව සම්බන්ධ වේ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"ඔබට ජංගම හෝ Wi-Fi ජාලයක් නොමැතිව පණිවිඩ යැවීමට සහ ලැබීමට හැක"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"චන්ද්රිකා පණිවිඩ යැවීම භාවිතා කරන්න ද?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"ජංගම හෝ Wi-Fi ජාලයකින් තොරව පණිවිඩ යැවීම සහ ලැබීම"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages විවෘත කරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 35283675c9ef..c50773d594a9 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepodarilo sa pripojiť k mobilnej sieti"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Skúste zmeniť predvolenú sieť. Zmeníte ju klepnutím."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tiesňové volania nie sú k dispozícii"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Nabudúce nezobrazovať"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Tiesňové volania vyžadujú mobilnú sieť"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornenia"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Presmerovanie hovorov"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Upozornenia týkajúce sa siete"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Sieť je k dispozícii"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stav pripojenia VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Čas a časové pásma"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Upozornenia od vášho správcu IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozornenia"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Predajná ukážka"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikácia je spustená"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikácie spotrebúvajúce batériu"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zväčšenie"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Načúvacie zariadenie"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Využitie dostupnosti"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Obrazovka"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Stiahnuť aplikáciu"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Bola vložená nová SIM karta"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Nastavte ju klepnutím"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vaše časové pásmo sa zmenilo"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Teraz ste v oblasti <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Nastaviť čas"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Nastaviť dátum"</string> <string name="date_time_set" msgid="4603445265164486816">"Nastaviť"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Režim jednej ruky"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Mimoriadne stmavenie"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Načúvacie zariadenia"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Odpojené"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Pripojené"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktívne"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Načítava sa"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvoľnite tlačidlá hlasitosti. Ak chcete zapnúť službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pridržte tri sekundy obe tlačidlá hlasitosti."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky dvoma prstami nahor a rýchlo uvoľnite."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky troma prstami nahor a rýchlo uvoľnite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Chcete prepnúť na mikrofón telefónu?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Chcete prepnúť na mikrofón načúvadla?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Keď chcete zlepšiť zvuk alebo ak je batéria načúvadla slabá. Týmto iba prepnete mikrofón počas hovoru."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Volať handsfree môžete pomocou mikrofónu načúvadla. Týmto iba prepnete mikrofón počas hovoru."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prepnúť"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavenia"</string> <string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Prebieha odhlásenie používateľa <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2456,6 +2461,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie je z bezpečnostných dôvodov pri zdieľaní obrazovky skrytý"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Chcete používať správy cez satelit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Odosielajte a prijímajte správy bez mobilnej siete či siete Wi‑Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index af6c95c70db4..134ee9df3f3d 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilnega omrežja ni mogoče doseči"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Poskusite spremeniti prednostno omrežje. Dotaknite se, če ga želite spremeniti."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Klicanje v sili ni na voljo"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ne prikaži več"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za klice v sili potrebujete mobilno omrežje"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Opozorila"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmerjanje klicev"</string> @@ -305,6 +304,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Opozorila omrežja"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Omrežje je na voljo"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Stanje omrežja VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Ura in časovni pasovi"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Opozorila skrbnika za IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Opozorila"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Predstavitev za maloprodajo"</string> @@ -312,6 +312,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikacija se izvaja"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacije, ki porabljajo energijo baterije"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Povečava"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Slušni pripomoček"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Uporaba funkcij za dostopnost"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Zaslon"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> porablja energijo baterije"</string> @@ -1409,6 +1410,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Prenos aplikacije"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nova kartica SIM je vstavljena"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Dotaknite se za nastavitev"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Časovni pas se je spremenil"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Zdaj ste v časovnem pasu <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Nastavi uro"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Nastavi datum"</string> <string name="date_time_set" msgid="4603445265164486816">"Nastavi"</string> @@ -1782,14 +1785,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni pripomočki"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Brez povezave"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Povezano"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktivno"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Nalaganje"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string> @@ -1800,6 +1799,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. Z dvema prstoma povlecite navzgor z dna zaslona in hitro spustite."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. S tremi prsti povlecite navzgor z dna zaslona in hitro spustite."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite preklopiti na mikrofon telefona?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite preklopiti na mikrofon za slušni aparat?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za boljši zvok ali pri skoraj prazni bateriji slušnega aparata. S tem preklopite mikrofon samo med klicem."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon za slušni aparat lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Preklopi"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavitve"</string> <string name="user_switched" msgid="7249833311585228097">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Odjavljanje uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string> @@ -2456,6 +2461,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Pri deljenju zaslona je vsebina aplikacije skrita zaradi varnosti"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Samodejno vzpostavljena povezava s satelitom"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Sporočila SMS lahko pošiljate in prejemate brez mobilnega omrežja ali omrežja Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Želite uporabiti satelitsko pošiljanje sporočil?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Pošiljanje in prejemanje sporočil brez mobilnega omrežja ali omrežja Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index d8fdb9a30d56..0a87e39e16df 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Rrjeti celular është i paarritshëm"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Provo të ndryshosh rrjetin e preferuar. Trokit për ta ndryshuar."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Telefonatat e urgjencës nuk ofrohen"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Mos e shfaq më"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Telefonatat e urgjencës kërkojnë një rrjet celular"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Sinjalizimet"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transferimi i telefonatave"</string> @@ -303,6 +302,8 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Sinjalizimet e rrjetit"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Ka rrjet të disponueshëm"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Statusi i VPN-së"</string> + <!-- no translation found for notification_channel_system_time (1660313368058030441) --> + <skip /> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Sinjalizimet nga administratori i teknologjisë së informacionit"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Sinjalizimet"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demonstrimi i shitjes me pakicë"</string> @@ -310,6 +311,8 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aplikacioni është në ekzekutim"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Aplikacionet që konsumojnë baterinë"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Zmadhimi"</string> + <!-- no translation found for notification_channel_accessibility_hearing_device (7816963856388758952) --> + <skip /> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Përdorimi i qasshmërisë"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekrani"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> po përdor baterinë"</string> @@ -1407,6 +1410,10 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Shkarko aplikacionin"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Është futur kartë e re SIM"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Trokit për ta konfiguruar"</string> + <!-- no translation found for time_zone_change_notification_title (5232503069219193218) --> + <skip /> + <!-- no translation found for time_zone_change_notification_body (6135793674904665585) --> + <skip /> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Cakto kohën"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Vendos datën"</string> <string name="date_time_set" msgid="4603445265164486816">"Cakto"</string> @@ -1780,14 +1787,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modaliteti i përdorimit me një dorë"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Shumë më i zbehtë"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Pajisjet e dëgjimit"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Shkëputur"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Lidhur"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktive"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Po ngarkohet"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lësho tastet e volumit. Për të aktivizuar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, shtyp dhe mbaj shtypur të dy tastet e volumit sërish për 3 sekonda."</string> @@ -1798,6 +1801,18 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 2 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 3 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zmadhimi"</string> + <!-- no translation found for hearing_device_switch_phone_mic_notification_title (6645178038359708836) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_title (4612074852145289569) --> + <skip /> + <!-- no translation found for hearing_device_switch_phone_mic_notification_text (1332426273666077412) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_text (8288368365767284208) --> + <skip /> + <!-- no translation found for hearing_device_notification_switch_button (3619524619430941300) --> + <skip /> + <!-- no translation found for hearing_device_notification_settings_button (6673651052880279178) --> + <skip /> <string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<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> po del…"</string> @@ -2454,6 +2469,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Përmbajtja e aplikacionit është fshehur nga ndarja e ekranit për arsye sigurie"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"U lidh automatikisht me satelitin"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mund të dërgosh dhe të marrësh mesazhe pa një rrjet celular apo rrjet Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Të përdoret shkëmbimi i mesazheve nëpërmjet satelitit?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Dërgo dhe merr mesazhe pa një rrjet celular ose Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 146855e730bb..33150dc3c3c2 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -88,8 +88,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Повезивање са мобилном мрежом није успело"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Не приказуј поново"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Хитни позиви захтевају мобилну мрежу"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Упозорења"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string> @@ -304,6 +303,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Обавештења у вези са мрежом"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Мрежа је доступна"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN-а"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Време и временске зоне"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Обавештења од ИТ администратора"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Упозорења"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Режим демонстрације за малопродајне објекте"</string> @@ -311,6 +311,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Апликације које троше батерију"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Увећање"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Слушни апарат"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Коришћење Приступачности"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Екран"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string> @@ -1408,6 +1409,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Преузмите апликацију"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Нова SIM картица је уметнута"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Додирните за подешавање"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Временска зона је промењена"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Сада сте у временској зони <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Подесите време"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Подешавање датума"</string> <string name="date_time_set" msgid="4603445265164486816">"Подеси"</string> @@ -1781,14 +1784,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим једном руком"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додатно затамни"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни апарати"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Веза је прекинута"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Повезано"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Активно"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Учитава се"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Пустите тастере за јачину звука. Да бисте укључили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, поново притисните и задржите оба тастера за јачину звука 3 секунде."</string> @@ -1799,6 +1798,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 2 прста и брзо пустите."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 3 прста и брзо пустите."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Желите да пређете на микрофон телефона?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Желите да пређете на микрофон слушног апарата?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"За бољи звук или ако је батерија слушног апарата скоро празна. Тиме се микрофон мења само током позива."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Можете да користите микрофон слушног апарата за хендсфри позивање. Тиме се микрофон мења само током позива."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Промени"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Подешавања"</string> <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> @@ -2455,6 +2460,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Садржај апликације је скривен за дељење садржаја екрана због безбедности"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Аутоматски повезано са сателитом"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да шаљете и примате поруке без мобилне или WiFi мреже"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Желите да користите сателитску размену порука?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Шаљите и примајте поруке без мобилне или WiFi мреже"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index ecb3c79cff45..ceb0fe1d6654 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Det går inte att nå mobilnätverket"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Testa att byta föredraget nätverk. Tryck om du vill ändra."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det går inte att ringa nödsamtal"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Visa inte igen"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Mobilnätverk krävs för att ringa nödsamtal"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Aviseringar"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Vidarekoppla samtal"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Nätverksvarningar"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Nätverk tillgängligt"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN-status"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Tid och tidszoner"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Aviseringar från IT-administratören"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Varningar"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo för återförsäljare"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"App körs"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Appar som drar batteri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Förstoring"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hörhjälpmedel"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Tillgänglighetsanvändning"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skärm"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> drar batteri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Ladda ned appen"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nytt SIM-kort har satts in"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Tryck om du vill konfigurera"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Din tidszon har ändrats"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Du befinner dig nu i <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Ange tid"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Ange datum"</string> <string name="date_time_set" msgid="4603445265164486816">"Ställ in"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enhandsläge"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extradimmat"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörhjälpmedel"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Frånkopplad"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Ansluten"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktiv"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Läser in"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Släpp volymknapparna. Du kan aktivera <xliff:g id="SERVICE_NAME">%1$s</xliff:g> genom att hålla båda volymknapparna nedtryckta i tre sekunder igen."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med två fingrar från skärmens nederkant och släpp snabbt."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med tre fingrar från skärmens nederkant och släpp snabbt."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Förstoring"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Vill du byta till telefonens mikrofon?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Vill du byta till hörapparatens mikrofon?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"För bättre ljud eller om hörapparaten har lite batteri. Detta byter bara mikrofon under samtalet."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Du kan använda hörapparatens mikrofon för handsfree-samtal. Detta byter bara mikrofon under samtalet."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Byt"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Inställningar"</string> <string name="user_switched" msgid="7249833311585228097">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Loggar ut <xliff:g id="NAME">%1$s</xliff:g> …"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Av säkerhetsskäl döljs appinnehållet vid skärmdelning"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiskt ansluten till satellit"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan skicka och ta emot meddelanden utan mobil- eller wifi-nätverk"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Vill du använda satellitmeddelanden?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Skicka och ta emot meddelanden utan ett mobil- eller wifi-nätverk"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 98c973140a65..58d71817a078 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Imeshindwa kufikia mtandao wa simu"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Jaribu kutumia mtandao unaopendelea. Gusa ili ubadilishe."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Huduma ya kupiga simu za dharura haipatikani"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Usionyeshe Tena"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Huduma ya kupiga simu za dharura inahitaji mtandao wa simu"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Arifa"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Kupeleka simu kwenye namba nyingine"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Arifa za mtandao"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Mtandao unapatikana"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Hali ya VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Saa na saa za maeneo"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Arifa kutoka kwa Msimamizi wako wa TEHAMA"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Arifa"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Onyesho la duka la rejareja"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Programu inaendelea kutekelezwa"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Programu zinazotumia betri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ukuzaji"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Vifaa vya kusikilizia"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Matumizi ya zana za ufikivu"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Skrini"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia betri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Pakua programu"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"SIM mpya imewekwa"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Gusa ili uiweke"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Saa za eneo lako zimebadilika"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Sasa unatumia saa za eneo za <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Weka saa"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Weka tarehe"</string> <string name="date_time_set" msgid="4603445265164486816">"Weka"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Hali ya kutumia kwa mkono mmoja"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Kipunguza mwangaza zaidi"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Vifaa vya kusaidia kusikia"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Haijaunganishwa"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Imeunganishwa"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Inatumika"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Inapakia"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Achilia vitufe vya sauti. Ili uwashe <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, bonyeza na ushikilie tena vitufe vyote vya sauti kwa sekunde 3."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 2 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 3 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukuzaji"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Ungependa kubadilisha utumie maikrofoni ya simu?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Ungependa kubadilisha utumie maikrofoni ya visaidizi vya kusikia?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Kwa sauti bora au iwapo chaji ya betri ya visaidizi vyako vya kusikia imepungua. Hali hii hubadilisha maikrofoni yako tu wakati unapiga simu."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Unaweza kutumia maikrofoni ya visaidizi vyako vya kusikia ili kupiga simu bila kugusa. Hali hii hubadilisha maikrofoni yako tu wakati unapiga simu."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Badilisha"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Mipangilio"</string> <string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Inamwondoa <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Maudhui ya programu yamefichwa ili yasionekane kwenye skrini ya pamoja kwa sababu za kiusalama"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Imeunganishwa kiotomatiki na satelaiti"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Unaweza kutuma na kupokea ujumbe bila mtandao wa simu au Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Ungependa kutuma ujumbe kupitia setilaiti?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Tuma na upokee ujumbe bila kutumia mtandao wa simu wala Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index f8b2bbc35b7d..59668bbff71d 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"மொபைல் நெட்வொர்க் கிடைக்கவில்லை"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"விருப்ப நெட்வொர்க்கை மாற்றவும். மாற்ற, தட்டவும்."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"அவசர அழைப்பைச் செய்ய முடியாது"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"மீண்டும் காட்டாதே"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"அவசர அழைப்புகளுக்கு மொபைல் நெட்வொர்க் தேவை"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"விழிப்பூட்டல்கள்"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"அழைப்பு திருப்பிவிடுதல்"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"நெட்வொர்க் விழிப்பூட்டல்கள்"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"நெட்வொர்க் உள்ளது"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN நிலை"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"நேரம் மற்றும் நேர மண்டலங்கள்"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT நிர்வாகியிடம் இருந்து வரும் விழிப்பூட்டல்கள்"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"விழிப்பூட்டல்கள்"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"விற்பனையாளர் டெமோ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ஆப்ஸ் இயங்குகிறது"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"பெரிதாக்கல்"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"செவித்துணைக் கருவி"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"அணுகல்தன்மை உபயோகம்"</string> <string name="notification_channel_display" msgid="6905032605735615090">"டிஸ்ப்ளே"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"பயன்பாட்டைப் பதிவிறக்கு"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"புதிய சிம் செருகப்பட்டது"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"அமைக்க, தட்டவும்"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"உங்கள் நேர மண்டலம் மாற்றப்பட்டது"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"நீங்கள் இப்போது இருப்பது: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"நேரத்தை அமை"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"தேதியை அமை"</string> <string name="date_time_set" msgid="4603445265164486816">"அமை"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ஒற்றைக் கைப் பயன்முறை"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"மிகக் குறைவான வெளிச்சம்"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"செவித்துணைக் கருவிகள்"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"இணைப்புநீக்கப்பட்டது"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"இணைக்கப்பட்டுள்ளது"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"செயலில் உள்ளது"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"ஏற்றுகிறது"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ஒலியளவு பட்டன்களை அழுத்துவதை நிறுத்துங்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> சேவையை இயக்க, ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு மீண்டும் அழுத்திப் பிடிக்கவும்."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 2 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 3 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"பெரிதாக்கல்"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ஃபோன் மைக்கிற்கு மாறவா?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"செவித்துணைக் கருவியின் மைக்கிற்கு மாறவா?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"மேம்பட்ட ஒலிக்கோ செவித்துணைக் கருவியில் பேட்டரி குறைவாக இருந்தாலோ. அழைப்பின்போது உங்கள் மைக்கை மட்டுமே இது மாற்றுகிறது."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"கைகளைப் பயன்படுத்தாமல் அழைக்க உங்கள் செவித்துணைக் கருவியின் மைக்ரோஃபோனைப் பயன்படுத்தலாம். அழைப்பின்போது உங்கள் மைக்கை மட்டுமே இது மாற்றுகிறது."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"மாற்று"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"அமைப்புகள்"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"பாதுகாப்பிற்காக, திரைப் பகிர்வில் இருந்து ஆப்ஸ் உள்ளடக்கம் மறைக்கப்பட்டுள்ளது"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"சாட்டிலைட்டுடன் தானாக இணைக்கப்பட்டது"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் நீங்கள் மெசேஜ்களை அனுப்பலாம் பெறலாம்"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"சாட்டிலைட் மெசேஜிங்கைப் பயன்படுத்தவா?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் மெசேஜ்களை அனுப்பலாம், பெறலாம்"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index bcd2865173d4..6285d776cfab 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"మొబైల్ నెట్వర్క్ అందుబాటులో లేదు"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ప్రాధాన్య నెట్వర్క్ను మార్చుకోవడానికి ప్రయత్నించండి. మార్చడానికి నొక్కండి."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"అత్యవసర కాలింగ్ అందుబాటులో లేదు"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"మళ్లీ చూపవద్దు"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ఎమర్జెన్సీ కాల్స్కు మొబైల్ నెట్వర్క్ అవసరమవుతుంది"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"అలర్ట్లు"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"కాల్ ఫార్వార్డింగ్"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"నెట్వర్క్ హెచ్చరికలు"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"నెట్వర్క్ అందుబాటులో ఉంది"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN స్టేటస్"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"టైమ్, టైమ్ జోన్లు"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"మీ IT నిర్వాహకుల నుండి వచ్చే హెచ్చరికలు"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"అలర్ట్లు"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"రిటైల్ డెమో"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"యాప్ అమలవుతోంది"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"బ్యాటరీని ఉపయోగిస్తున్న యాప్లు"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"మ్యాగ్నిఫికేషన్"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"వినికిడి పరికరం"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"యాక్సెసిబిలిటీ వినియోగం"</string> <string name="notification_channel_display" msgid="6905032605735615090">"డిస్ప్లే చేయండి"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> బ్యాటరీని ఉపయోగిస్తోంది"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"యాప్ని డౌన్లోడ్ చేయి"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"కొత్త SIM చొప్పించారు"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"దీన్ని సెటప్ చేయడానికి నొక్కండి"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"మీ టైమ్ జోన్ మారింది"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"మీరు ఇప్పుడు <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g>లో (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ఉన్నారు"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"సమయాన్ని సెట్ చేయండి"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"తేదీని సెట్ చేయండి"</string> <string name="date_time_set" msgid="4603445265164486816">"సెట్ చేయి"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"వన్-హ్యాండెడ్ మోడ్"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ఎక్స్ట్రా డిమ్"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరాలు"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"డిస్కనెక్ట్ అయింది"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"కనెక్ట్ చేయబడింది"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"యాక్టివ్"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"లోడ్ అవుతోంది"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"తర్వాతిసారి మీరు ఈ షార్ట్కట్ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 2 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"తర్వాతిసారి మీరు ఈ షార్ట్కట్ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 3 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ఫోన్ మైక్కు మారాలా?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"వినికిడి పరికరం మైక్కు మారాలా?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"మెరుగైన సౌండ్ కోసం లేదా మీ వినికిడి పరికరం బ్యాటరీ తక్కువగా ఉన్నప్పుడు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్ను మారుస్తుంది."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"హ్యాండ్స్-ఫ్రీ కాలింగ్ కోసం మీరు మీ వినికిడి పరికరాన్ని ఉపయోగించవచ్చు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్ను మారుస్తుంది."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"మారండి"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"సెట్టింగ్లు"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"సెక్యూరిటీ కోసం స్క్రీన్ షేర్ నుండి యాప్ కంటెంట్ దాచబడింది"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"శాటిలైట్కు ఆటోమేటిక్గా కనెక్ట్ చేయబడింది"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"మీరు మొబైల్ లేదా Wi-Fi నెట్వర్క్ లేకుండా మెసేజ్లను పంపవచ్చు, స్వీకరించవచ్చు"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"శాటిలైట్ మెసేజింగ్ను ఉపయోగించాలనుకుంటున్నారా?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"మొబైల్ లేదా Wi-Fi నెట్వర్క్ లేకుండా మెసేజ్లను పంపండి, స్వీకరించండి"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messagesను తెరవండి"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 0e66e371f722..557286128053 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"เชื่อมต่อเครือข่ายมือถือไม่ได้"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ลองเปลี่ยนเครือข่ายที่ต้องการ แตะเพื่อเปลี่ยน"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"โทรหาหมายเลขฉุกเฉินไม่ได้"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"ไม่ต้องแสดงอีก"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"การโทรหาหมายเลขฉุกเฉินต้องใช้เครือข่ายมือถือ"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"การแจ้งเตือน"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"การโอนสาย"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"การแจ้งเตือนเครือข่าย"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"มีเครือข่ายพร้อมใช้งาน"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"สถานะ VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"เวลาและเขตเวลา"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"การแจ้งเตือนจากผู้ดูแลระบบไอทีของคุณ"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"การแจ้งเตือน"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"การสาธิตสำหรับผู้ค้าปลีก"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"แอปที่ทำงานอยู่"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"แอปหลายแอปกำลังใช้แบตเตอรี่"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"การขยาย"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"เครื่องช่วยฟัง"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"การใช้งานการช่วยเหลือพิเศษ"</string> <string name="notification_channel_display" msgid="6905032605735615090">"จอแสดงผล"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้แบตเตอรี่"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ดาวน์โหลดแอป"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"ใส่ซิมใหม่แล้ว"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"แตะเพื่อตั้งค่า"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"เขตเวลามีการเปลี่ยนแปลง"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"ตอนนี้คุณอยู่ในเขตเวลา <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"ตั้งเวลา"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"ตั้งวันที่"</string> <string name="date_time_set" msgid="4603445265164486816">"ตั้งค่า"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"โหมดมือเดียว"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"หรี่แสงเพิ่มเติม"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"เครื่องช่วยฟัง"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"เลิกเชื่อมต่อแล้ว"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"เชื่อมต่อแล้ว"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"ใช้งานอยู่"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"กำลังโหลด"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ปล่อยปุ่มปรับระดับเสียง หากต้องการเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ให้กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้อีกครั้งเป็นเวลา 3 วินาที"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 3 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"การขยาย"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"เปลี่ยนไปใช้ไมโครโฟนของโทรศัพท์ไหม"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"เปลี่ยนไปใช้ไมโครโฟนของเครื่องช่วยฟังไหม"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"เพื่อให้เสียงดีขึ้นหรือในกรณีที่แบตเตอรี่ของเครื่องช่วยฟังใกล้หมด การดำเนินการนี้เพียงแค่เปลี่ยนไมโครโฟนระหว่างการโทรเท่านั้น"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"คุณใช้ไมโครโฟนของเครื่องช่วยฟังเพื่อโทรแบบแฮนด์ฟรีได้ การดำเนินการนี้เพียงแค่เปลี่ยนไมโครโฟนระหว่างการโทรเท่านั้น"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"เปลี่ยน"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"การตั้งค่า"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอแล้วเพื่อความปลอดภัย"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"เชื่อมต่อกับดาวเทียมโดยอัตโนมัติ"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"ใช้การรับส่งข้อความผ่านดาวเทียมไหม"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"รับและส่งข้อความโดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 0ab4fb2901b6..44832c87a3a7 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Hindi makakonekta sa mobile network"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Subukang baguhin ang gustong network. I-tap para baguhin."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hindi available ang pang-emergency na pagtawag"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Huwag Ipakita Ulit"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Kailangan ng mobile network para sa mga emergency na tawag"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Mga Alerto"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Pagpasa ng tawag"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Mga alerto sa network"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Available ang network"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Status ng VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Oras at mga time zone"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Mga alerto mula sa iyong IT admin"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Mga Alerto"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Retail demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Tumatakbo ang app"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Mga app na kumokonsumo ng baterya"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Pag-magnify"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Hearing device"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Paggamit sa pagiging accessible"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Display"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Gumagamit ng baterya ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> @@ -880,7 +881,7 @@ <item msgid="7740243458912727194">"Mobile"</item> <item msgid="8526146065496663766">"Trabaho"</item> <item msgid="8150904584178569699">"Fax sa Trabaho"</item> - <item msgid="4537253139152229577">"Fax sa Tahanan"</item> + <item msgid="4537253139152229577">"Home Fax"</item> <item msgid="6751245029698664340">"Pager"</item> <item msgid="1692790665884224905">"Iba pa"</item> <item msgid="6216981255272016212">"Custom"</item> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"I-download ang app"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nakalagay na ang bagong SIM"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"I-tap upang i-set up ito"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Nagbago ang iyong time zone"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Nasa <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) ka na ngayon."</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Magtakda ng oras"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Itakda ang petsa"</string> <string name="date_time_set" msgid="4603445265164486816">"Itakda"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"One-Hand mode"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Extra dim"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Mga hearing device"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Nadiskonekta"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Nakakonekta"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Aktibo"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Naglo-load"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Bitawan ang mga volume key. Para i-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, muling pindutin nang matagal ang dalawang volume key sa loob ng 3 segundo."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 2 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 3 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pag-magnify"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Lumipat sa mikropono ng telepono?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Lumipat sa mikropono ng hearing aid?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Para sa mas malinaw na tunog o kung paubos na ang baterya ng iyong hearing aid. Inililipat lang nito ang iyong mikropono habang nasa tawag ka."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puwede mong gamitin ang mikropono ng iyong hearing aid para sa hands-free na pagtawag. Inililipat lang nito ang iyong mikropono habang nasa tawag ka."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Lumipat"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Mga Setting"</string> <string name="user_switched" msgid="7249833311585228097">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Nila-log out si <xliff:g id="NAME">%1$s</xliff:g>..."</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Nakatago ang content ng app mula sa pagbabahagi ng screen para sa seguridad"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Awtomatikong nakakonekta sa satellite"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Puwede kang magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Gumamit ng satellite messaging?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 78ce9d4d3ae5..1a8d373a2aa2 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil ağa erişilemiyor"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tercih edilen ağı değiştirmeyi deneyin. Değiştirmek için dokunun."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Acil durum çağrısı kullanılamaz"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Bir daha gösterme"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Acil durum aramaları için mobil ağ gereklidir"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Uyarılar"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Çağrı yönlendirme"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Ağ uyarıları"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Ağ mevcut"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN durumu"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Saat ve saat dilimleri"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"IT yöneticinizden uyarılar"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Uyarılar"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Mağaza demo"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Uygulama çalışıyor"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Pil kullanan uygulamalar"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Büyütme"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"İşitme cihazı"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Erişilebilirlik kullanımı"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Ekran"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> pil kullanıyor"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Uygulama indir"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Yeni SIM kart takıldı"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Kurmak için dokunun"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Saat diliminiz değişti"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Artık <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) saat dilimindesiniz"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Saati ayarlayın"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Tarihi ayarlayın"</string> <string name="date_time_set" msgid="4603445265164486816">"Ayarla"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Tek El modu"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ekstra loş"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"İşitme cihazları"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Bağlı değil"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Bağlı"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Etkin"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Yükleniyor"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ses seviyesi tuşlarını bırakın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini etkinleştirmek için her iki ses seviyesi tuşuna yeniden basıp 3 saniye boyunca basılı tutun."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 2 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 3 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofonuna geçilsin mi?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"İşitme cihazı mikrofonuna geçilsin mi?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha iyi ses kalitesi için veya işitme cihazınızın pili azaldığında Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Eller serbest modunda arama yapmak için işitme cihazı mikrofonunu kullanabilirsiniz. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Geçiş yap"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string> <string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"<xliff:g id="NAME">%1$s</xliff:g> hesabından çıkış yapılıyor…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Uygulama içerikleri, güvenlik nedeniyle ekran paylaşımında gizlendi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Uyduya otomatik olarak bağlandı"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil veya kablosuz ağa bağlı olmadan mesaj alıp gönderebilirsiniz"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Uydu üzerinden mesajlaşma kullanılsın mı?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil veya kablosuz ağ kullanmadan mesaj gönderip alın"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index a98fda433f8f..5e6f9ec90037 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -89,8 +89,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не вдається під’єднатися до мобільної мережі"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Спробуйте змінити вибрану мережу. Торкніться, щоб це зробити."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Екстрені виклики недоступні"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Більше не показувати"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Щоб здійснювати екстрені виклики, потрібне з’єднання з мобільною мережею"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сповіщення"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресація виклику"</string> @@ -305,6 +304,8 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Сповіщення мережі"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Мережа доступна"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Статус мережі VPN"</string> + <!-- no translation found for notification_channel_system_time (1660313368058030441) --> + <skip /> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Сповіщення від ІТ-адміністратора"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Сповіщення"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Демо-режим для роздрібної торгівлі"</string> @@ -312,6 +313,8 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Працює додаток"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Додатки, що використовують заряд акумулятора"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Збільшення"</string> + <!-- no translation found for notification_channel_accessibility_hearing_device (7816963856388758952) --> + <skip /> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Використання спеціальних можливостей"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Дисплей"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує заряд акумулятора"</string> @@ -1409,6 +1412,10 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Завантажити додаток"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Вставлено нову SIM-карту"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Торкніться, щоб налаштувати"</string> + <!-- no translation found for time_zone_change_notification_title (5232503069219193218) --> + <skip /> + <!-- no translation found for time_zone_change_notification_body (6135793674904665585) --> + <skip /> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Установити час"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Установити дату"</string> <string name="date_time_set" msgid="4603445265164486816">"Застосувати"</string> @@ -1782,14 +1789,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Режим керування однією рукою"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Додаткове зменшення яскравості"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухові апарати"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Від’єднано"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Під’єднано"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Активний"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Завантаження"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Відпустіть клавіші гучності. Щоб увімкнути сервіс <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натисніть і втримуйте обидві клавіші гучності протягом 3 секунд."</string> @@ -1800,6 +1803,18 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть двома пальцями вгору від низу екрана й швидко відпустіть."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть трьома пальцями вгору від низу екрана й швидко відпустіть."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Збільшення"</string> + <!-- no translation found for hearing_device_switch_phone_mic_notification_title (6645178038359708836) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_title (4612074852145289569) --> + <skip /> + <!-- no translation found for hearing_device_switch_phone_mic_notification_text (1332426273666077412) --> + <skip /> + <!-- no translation found for hearing_device_switch_hearing_mic_notification_text (8288368365767284208) --> + <skip /> + <!-- no translation found for hearing_device_notification_switch_button (3619524619430941300) --> + <skip /> + <!-- no translation found for hearing_device_notification_settings_button (6673651052880279178) --> + <skip /> <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> @@ -2456,6 +2471,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"З міркувань безпеки вміст додатка приховано під час показу екрана"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматично підключено до супутника"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Ви можете надсилати й отримувати повідомлення, не використовуючи Wi-Fi або мобільну мережу"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Скористатися супутниковим обміном повідомленнями?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Надсилайте й отримуйте текстові повідомлення без мобільної мережі або Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Відкрийте Повідомлення"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 0a0047422a74..7ddd7cb8a02a 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"موبائل نیٹ ورک تک رسائی نہیں ہو سکتی"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ترجیحی نیٹ ورک تبدیل کر کے دیکھیں۔ تبدیل کرنے کے لیے تھپتھپائیں۔"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ایمرجنسی کالنگ دستیاب نہیں ہے"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"دوبارہ نہ دکھائیں"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ہنگامی کالز کو موبائل نیٹ ورک کی ضرورت ہے"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"الرٹس"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"کال فارورڈنگ"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"نیٹ ورک الرٹس"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"نیٹ ورک دستیاب ہے"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN اسٹیٹس"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"وقت اور ٹائم زونز"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"آپ کے IT منتظم کی جانب سے الرٹس"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"الرٹس"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"ریٹیل ڈیمو"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"ایپ چل رہی ہے"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"ایپس بیٹری خرچ کر رہی ہیں"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"میگنیفکیشن"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"آلہ سماعت"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"ایکسیسبیلٹی کا استعمال"</string> <string name="notification_channel_display" msgid="6905032605735615090">"ڈسپلے"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> بیٹری کا استعمال کر رہی ہے"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"ایپ ڈاؤن لوڈ کریں"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"نئی SIM داخل ہو گئی"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"اسے سیٹ اپ کرنے کیلئے تھپتھپائیں"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"آپ کا ٹائم زون تبدیل ہو گیا"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"آپ اب <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>) میں ہیں"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"وقت سیٹ کریں"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"تاریخ سیٹ کریں"</string> <string name="date_time_set" msgid="4603445265164486816">"سیٹ کریں"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"ایک ہاتھ کی وضع"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"اضافی مدھم"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعتی آلات"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"غیر منسلک ہے"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"منسلک ہے"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"فعال"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"لوڈ ہو رہا ہے"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"والیوم کی کلیدوں کو ریلیز کریں <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کرنے کے لیے، والیوم کی دونوں کلیدوں کو دوبارہ 3 سیکنڈ تک چھوئیں اور دبائے رکھیں۔"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 2 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 3 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"میگنیفکیشن"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"فون کے مائیک پر سوئچ کریں؟"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"سماعتی آلہ کے مائیک پر سوئچ کریں؟"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"بہتر آواز کے لیے یا اگر آپ کے سماعتی آلہ کی بیٹری کم ہے۔ یہ صرف کال کے دوران آپ کا مائیک سوئچ کرتا ہے۔"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"آپ ہینڈز فری کالنگ کے لیے اپنا سماعتی آلہ مائیکروفون استعمال کر سکتے ہیں۔ یہ صرف کال کے دوران آپ کا مائیک سوئچ کرتا ہے۔"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"سوئچ کریں"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ترتیبات"</string> <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> @@ -1974,7 +1979,7 @@ <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"آن ہے"</string> <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"آف ہے"</string> <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string> - <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string> + <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string> <string name="zen_mode_trigger_summary_range_words" msgid="7228261413029290750">"<xliff:g id="START">%1$s</xliff:g> تا <xliff:g id="END">%2$s</xliff:g>"</string> <string name="zen_mode_trigger_summary_combined" msgid="6492381546327807669">"<xliff:g id="DAYS">%1$s</xliff:g>، <xliff:g id="TIMES">%2$s</xliff:g>"</string> <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"کوئی بھی کیلنڈر"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"سیکیورٹی کے مد نظر ایپ کا مواد اسکرین کے اشتراک سے چھپا ہوا ہے"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"سٹلائٹ سے خودکار طور پر منسلک ہے"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"آپ موبائل یا Wi-Fi نیٹ ورک کے بغیر پیغامات بھیج اور موصول کر سکتے ہیں"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"سیٹلائٹ پیغام رسانی کا استعمال کریں؟"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"موبائل یا Wi-Fi نیٹ ورک کے بغیر پیغامات بھیجیں اور موصول کریں"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"پیغامات ایپ کو کھولیں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 2f158f411a47..c1697953eb53 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil tarmoqqa ulanib bo‘lmadi"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tarmoq turini almashtiring. Almashtirish uchun bosing."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Favqulodda chaqiruv ishlamayapti"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Boshqa koʻrsatilmasin"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Favqulodda chaqiruvlar uchun mobil tarmoq zarur"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ogohlantirishlar"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Chaqiruvlarni uzatish"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Tarmoqqa oid bildirgilar"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Tarmoq mavjud"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN holati"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Vaqt va vaqt mintaqalari"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Administratordan xabarlar"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Ogohlantirishlar"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Demo rejim"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Ilova faol"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Batareya quvvatini sarflayotgan ilovalar"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Kattalashtirish"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Eshitish qurilmasi"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Qulayliklar ishlatilishi"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Displey"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Ilovani yuklab olish"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Yangi SIM karta solindi"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Sozlash uchun bosing"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Vaqt mintaqangiz oʻzgardi"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Endi bu yerdasiz: <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Vaqtni o‘rnatish"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Sanani kiritish"</string> <string name="date_time_set" msgid="4603445265164486816">"O‘rnatish"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Ixcham rejim"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Juda xira"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eshitish qurilmalari"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Uzildi"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Ulandi"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Faol"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Yuklanmoqda"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Tovush tugmalarini qoʻyib yuboring. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatini yoqish uchun ikkala tovush tugmasini 3 soniya bosib turing."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofoniga almashtirilsinmi?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eshitish moslamasi mikrofoniga almashtirilsinmi?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Tovush yaxshilanishi uchun yoki eshitish moslamasi batareyasi quvvati kam boʻlsa. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Garniturali chaqiruv uchun eshitish moslamasi mikrofonidan foydalanish mumkin. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Almashtirish"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Sozlamalar"</string> <string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <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> hisobidan chiqilmoqda…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Ekran namoyishida xavfsizlik maqsadida ilova kontenti berkitildi"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Sputnikka avtomatik ulandi"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil yoki Wi-Fi tarmoqsiz xabarlarni yuborishingiz va qabul qilishingiz mumkin"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Sputnik orqali xabarlashuv ishlatilsinmi?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Mobil yoki Wi-Fi tarmoq blan aloqa yoʻqligida xabar yuboring va qabul qiling"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index adb3e023d59a..11b57703d339 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Không thể kết nối với mạng di động"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Hãy thử thay đổi mạng ưu tiên. Nhấn để thay đổi."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Không có dịch vụ gọi khẩn cấp"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Không hiện lại"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Cần có mạng di động để thực hiện các cuộc gọi khẩn cấp"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Thông báo"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Chuyển tiếp cuộc gọi"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Cảnh báo mạng"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Có mạng"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Trạng thái VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Thời gian và múi giờ"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Thông báo từ quản trị viên CNTT của bạn"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Cảnh báo"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Giới thiệu bán lẻ"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Ứng dụng đang chạy"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Các ứng dụng tiêu thụ pin"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Phóng to"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Thiết bị trợ thính"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Việc sử dụng tính năng hỗ trợ tiếp cận"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Hiển thị"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang sử dụng pin"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Tải xuống ứng dụng"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Đã lắp SIM mới"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Nhấn để thiết lập"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Múi giờ của bạn đã thay đổi"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Bạn đang ở múi giờ <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Đặt giờ"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Đặt ngày"</string> <string name="date_time_set" msgid="4603445265164486816">"Đặt"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Chế độ một tay"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Siêu tối"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Thiết bị trợ thính"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Đã ngắt kết nối"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Đã kết nối"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Đang hoạt động"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Đang tải"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Thả phím âm lượng. Để bật <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, hãy nhấn và giữ cả 2 phím âm lượng trong 3 giây một lần nữa."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 2 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 3 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Phóng to"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Chuyển sang micrô trên điện thoại?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Chuyển sang micrô của thiết bị trợ thính?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Để có âm thanh tốt hơn hoặc nếu thiết bị trợ thính của bạn sắp hết pin. Thao tác này chỉ chuyển micrô của bạn trong cuộc gọi."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Bạn có thể sử dụng micrô của thiết bị trợ thính để gọi điện mà không cần dùng tay. Thao tác này chỉ chuyển micrô của bạn trong cuộc gọi."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Chuyển"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Cài đặt"</string> <string name="user_switched" msgid="7249833311585228097">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Đang đăng xuất <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Nội dung ứng dụng bị ẩn khỏi tính năng chia sẻ màn hình vì lý do bảo mật"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Đã tự động kết nối với vệ tinh"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Bạn có thể gửi và nhận tin nhắn mà không cần có mạng di động hoặc mạng Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Sử dụng tính năng nhắn tin qua vệ tinh?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Gửi và nhận tin nhắn mà không cần mạng di động hoặc Wi-Fi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index dd90e25114d8..4a38b933b000 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"无法连接到移动网络"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"请尝试更改首选网络。点按即可更改。"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"无法使用紧急呼救服务"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"不再显示"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"紧急呼叫需要使用移动网络"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"提醒"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"来电转接"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"网络提醒"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"有可用的网络"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN 状态"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"时间和时区"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"您的 IT 管理员发来的提醒"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"提醒"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"零售演示模式"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"应用正在运行中"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"消耗电量的应用"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大功能"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"助听装置"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"无障碍功能使用情况"</string> <string name="notification_channel_display" msgid="6905032605735615090">"显示屏"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在消耗电量"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"下载应用"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"已插入新 SIM 卡"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"点按即可进行设置"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"您的时区已更改"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"您现在位于<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"设置时间"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"设置日期"</string> <string name="date_time_set" msgid="4603445265164486816">"设置"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"单手模式"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"极暗"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听装置"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"已断开连接"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"已连接"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"活跃"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"正在加载"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快捷手势时,将打开此功能。用 2 根手指从画面底部向上滑动,然后快速松开。"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快捷手势时,将打开此功能。用 3 根手指从画面底部向上滑动,然后快速松开。"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切换为手机麦克风吗?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切换为助听器麦克风吗?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音质,或在助听器电池电量不足时使用。此操作只会切换通话期间的麦克风。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。此操作只会切换通话期间的麦克风。"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切换"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"设置"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见,屏幕共享画面已隐藏此应用的内容"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"使用卫星消息功能?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"即使没有移动网络或 WLAN 网络,也能收发消息"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index d34ed3d68dbc..cd428895c4d0 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連線至流動網絡"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網絡。輕按即可變更。"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"不要再顯示"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"撥打緊急電話需要使用流動網絡"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉駁"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"網絡通知"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"有可用的網絡"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN 狀態"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"時間和時區"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"來自 IT 管理員的通知"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"通知"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"零售示範"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"應用程式正在執行"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"耗用電量的應用程式"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"助聽器"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"無障礙功能使用情況"</string> <string name="notification_channel_display" msgid="6905032605735615090">"顯示屏"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用電量"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"下載應用程式"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"已插入新的 SIM 卡"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"輕按即可設定"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"你的時區已變更"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"你現在處於 <xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"設定時間"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"日期設定"</string> <string name="date_time_set" msgid="4603445265164486816">"設定"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"已中斷連線"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"已連線"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"運作中"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"正在載入"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"鬆開音量鍵。如果要開 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時㩒住兩個音量鍵 3 秒。"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切換至手機麥克風嗎?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切換至助聽器麥克風嗎?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音質,也在助聽器電量不足時適用。此操作只會切換通話期間的麥克風。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。此操作只會切換通話期間的麥克風。"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,應用程式內容已從分享螢幕畫面隱藏"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連線至衛星"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"你可在沒有流動/Wi-Fi 網絡的情況下收發訊息"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"要使用衛星訊息嗎?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"在沒有流動網絡或 Wi-Fi 網絡的情況下收發短訊"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 09d1a7b4e1ce..c8ae6793a4e3 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連上行動網路"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網路。輕觸即可變更。"</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"不要再顯示"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"撥打緊急電話需要使用行動網路"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"快訊"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉接"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"網路警示"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"有可用的網路"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"VPN 狀態"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"時間和時區"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"來自 IT 管理員的快訊"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"快訊"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"零售商展示模式"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"應用程式執行中"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"正在耗用電量的應用程式"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"放大"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"助聽器"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"無障礙功能使用情形"</string> <string name="notification_channel_display" msgid="6905032605735615090">"螢幕"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在耗用電量"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"下載應用程式"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"已插入新的 SIM 卡"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"輕觸這裡即可進行設定"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"時區已變更"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"現在位於<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"設定時間"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"日期設定"</string> <string name="date_time_set" msgid="4603445265164486816">"設定"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"單手模式"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"超暗"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"連線中斷"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"已連線"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"運作中"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"載入中"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"放開音量鍵。如要開啟 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時按住音量調高鍵和調低鍵 3 秒。"</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用這個捷徑時,就會開啟這項功能。請用 2 指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用這個捷徑時,就會開啟這項功能。請用 3 指從螢幕底部向上滑動並快速放開。"</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切換到手機麥克風嗎?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切換到助聽器麥克風嗎?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可享更好的音質,或在助聽器電量過低時使用。麥克風只會在通話期間切換。"</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"免持通話時,可以使用助聽器麥克風。麥克風只會在通話期間切換。"</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string> <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> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面隱藏了這個應用程式的內容"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"要使用衛星訊息功能嗎?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"即使沒有行動或 Wi-Fi 網路,還是可以收發訊息"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index cfc060ac4bab..7658189f3f55 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -87,8 +87,7 @@ <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ayikwazi ukufinyelela kunethiwekhi yeselula"</string> <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Zama ukushintsha inethiwekhi encanyelwayo. Thepha ukuze ushintshe."</string> <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ukushaya okuphuthumayo akutholakali"</string> - <!-- no translation found for emergency_calling_do_not_show_again (5034171343309733068) --> - <skip /> + <string name="emergency_calling_do_not_show_again" msgid="5034171343309733068">"Ungaphindi Ubonise Futhi"</string> <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Amakholi aphuthumayo adinga inethiwekhi yeselula"</string> <string name="notification_channel_network_alert" msgid="4788053066033851841">"Izexwayiso"</string> <string name="notification_channel_call_forward" msgid="8230490317314272406">"Ukudlulisa ikholi"</string> @@ -303,6 +302,7 @@ <string name="notification_channel_network_alerts" msgid="6312366315654526528">"Izexwayiso zenethiwekhi"</string> <string name="notification_channel_network_available" msgid="6083697929214165169">"Inethiwekhi iyatholakala"</string> <string name="notification_channel_vpn" msgid="1628529026203808999">"Isimo se-VPN"</string> + <string name="notification_channel_system_time" msgid="1660313368058030441">"Isikhathi nezoni yesikhathi"</string> <string name="notification_channel_device_admin" msgid="6384932669406095506">"Izxwayiso kusuka kumlawuli wakho we-IT"</string> <string name="notification_channel_alerts" msgid="5070241039583668427">"Izexwayiso"</string> <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Idemo yokuthenga"</string> @@ -310,6 +310,7 @@ <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Uhlelo loksuebenza olusebenzayo"</string> <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Izinhlelo zokusebenza ezidla ibhethri"</string> <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Ukukhuliswa"</string> + <string name="notification_channel_accessibility_hearing_device" msgid="7816963856388758952">"Insizakuzwa"</string> <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Ukusetshenziswa kokufinyeleleka"</string> <string name="notification_channel_display" msgid="6905032605735615090">"Bonisa"</string> <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa ibhethri"</string> @@ -1407,6 +1408,8 @@ <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Landa uhlelo lokusebenza"</string> <string name="carrier_app_notification_title" msgid="5815477368072060250">"Kufakwe i-SIM entsha"</string> <string name="carrier_app_notification_text" msgid="6567057546341958637">"Thepha ukuze uyisethe"</string> + <string name="time_zone_change_notification_title" msgid="5232503069219193218">"Izoni yakho yesikhathi ishintshile"</string> + <string name="time_zone_change_notification_body" msgid="6135793674904665585">"Manje sewuku-<xliff:g id="TIME_ZONE_DISPLAY_NAME">%1$s</xliff:g> (<xliff:g id="TIME_ZONE_OFFSET">%2$s</xliff:g>)"</string> <string name="time_picker_dialog_title" msgid="9053376764985220821">"Hlela isikhathi"</string> <string name="date_picker_dialog_title" msgid="5030520449243071926">"Setha idethi"</string> <string name="date_time_set" msgid="4603445265164486816">"Hlela"</string> @@ -1780,14 +1783,10 @@ <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Imodi yesandla esisodwa"</string> <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Ukufiphaza okwengeziwe"</string> <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Amadivayizi okuzwa"</string> - <!-- no translation found for hearing_device_status_disconnected (497547752953543832) --> - <skip /> - <!-- no translation found for hearing_device_status_connected (2149385149669918764) --> - <skip /> - <!-- no translation found for hearing_device_status_active (4770378695482566032) --> - <skip /> - <!-- no translation found for hearing_device_status_loading (5717083847663109747) --> - <skip /> + <string name="hearing_device_status_disconnected" msgid="497547752953543832">"Inqamukile"</string> + <string name="hearing_device_status_connected" msgid="2149385149669918764">"Ixhunyiwe"</string> + <string name="hearing_device_status_active" msgid="4770378695482566032">"Kuyasebenza"</string> + <string name="hearing_device_status_loading" msgid="5717083847663109747">"Iyalayisha"</string> <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string> <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string> <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Khipha okhiye bevolumu. Ukuze uvule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>, cindezela bese ubamba bobabili okhiye bevolumu futhi imizuzwana emi-3."</string> @@ -1798,6 +1797,12 @@ <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-2 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string> <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-3 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string> <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukukhuliswa"</string> + <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Shintshela kumakrofoni yefoni?"</string> + <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Shintshela kumakrofoni yomshini wendlebe?"</string> + <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Ukuze uthole umsindo ongcono noma uma ibhethri lakho lomshini wendlebe liphansi. Lokhu kushintsha kuphela imakrofoni yakho ngesikhathi sekholi."</string> + <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Ungasebenzisa imakrofoni yakho yomshini wendlebe ekufoneni ngehands-free. Lokhu kushintsha kuphela imakrofoni yakho ngesikhathi sekholi."</string> + <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Shintsha"</string> + <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Amasethingi"</string> <string name="user_switched" msgid="7249833311585228097">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string> <string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="7216437629179710359">"Iyaphuma <xliff:g id="NAME">%1$s</xliff:g>…"</string> @@ -2454,6 +2459,8 @@ <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Okuqukethwe kwe-app kufihliwe kusuka ekwabelaneni kwesikrini ngokuvikelwa"</string> <string name="satellite_notification_title" msgid="4026338973463121526">"Ixhumeke ngokuzenzakalelayo kusathelayithi"</string> <string name="satellite_notification_summary" msgid="5207364139430767162">"Ungathumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma ye-Wi-Fi"</string> + <!-- no translation found for satellite_notification_summary_with_data (6486843676720429049) --> + <skip /> <string name="satellite_notification_manual_title" msgid="1097504441849466279">"Sebenzisa ukuthumela umyalezo ngesethelayithi?"</string> <string name="satellite_notification_manual_summary" msgid="901206289846283445">"Thumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma yeWiFi"</string> <string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 8bf61bbcf55e..bd1d3033165e 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2737,7 +2737,7 @@ The default is true. --> <attr name="windowIsFrameRatePowerSavingsBalanced" format="boolean"/> - <!-- Flag indicating whether this window would opt-out the edge-to-edge enforcement. + <!-- Flag indicating whether this window would opt out the edge-to-edge enforcement. <p>If this is false, the edge-to-edge enforcement will be applied to the window if it belongs to an app targeting @@ -2757,8 +2757,9 @@ The Configuration will be stable regardless of the system insets change. </ul> - <p>If this is true, the edge-to-edge enforcement won't be applied. However, this - attribute will be deprecated and disabled in a future SDK level. + <p>If this is true, the edge-to-edge enforcement won't be applied. But if the window + belongs to an app targeting {@link android.os.Build.VERSION_CODES#BAKLAVA BAKLAVA} or + above, this attribute is ignored and the enforcement is applied regardless. <p>This is false by default. --> <attr name="windowOptOutEdgeToEdgeEnforcement" format="boolean"/> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index e14cffd72b0c..ec1be83dcae6 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -3156,6 +3156,16 @@ with admin privileges and admin privileges can be granted/revoked from existing users. --> <bool name="config_enableMultipleAdmins">false</bool> + <!-- Whether to start stopped users before their scheduled alarms. If set to true, users will be + started in background before the alarm time so that it can go off. If false, alarms of + stopped users will not go off and users will remain stopped. --> + <bool name="config_allowAlarmsOnStoppedUsers">true</bool> + + <!-- Whether notification is shown to foreground user when alarm/timer goes off on background + user. If set to true, foreground user will receive a notification with ability to mute + sound or switch user. If false, system notification will not be shown. --> + <bool name="config_showNotificationForBackgroundUserAlarms">true</bool> + <!-- Whether there is a communal profile which should always be running. Only relevant for Headless System User Mode (HSUM) devices. --> <bool name="config_omnipresentCommunalUser">false</bool> @@ -5225,10 +5235,6 @@ <!-- Whether or not swipe up gesture's opt-in setting is available on this device --> <bool name="config_swipe_up_gesture_setting_available">true</bool> - <!-- Applications which are disabled unless matching a particular sku --> - <string-array name="config_disableApksUnlessMatchedSku_apk_list" translatable="false" /> - <string-array name="config_disableApkUnlessMatchedSku_skus_list" translatable="false" /> - <!-- Whether or not we should show the option to show battery percentage --> <bool name="config_battery_percentage_setting_available">true</bool> @@ -7313,4 +7319,8 @@ <!-- Whether the device supports Wi-Fi USD feature. --> <bool name="config_deviceSupportsWifiUsd">false</bool> + + <!-- Array containing the notification assistant service adjustments that are not supported by + default on this device--> + <string-array translatable="false" name="config_notificationDefaultUnsupportedAdjustments" /> </resources> diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index 666f1cf39fe3..965c69d16d79 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -84,7 +84,7 @@ CarrierConfigManager#KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_STRING_ARRAY. If 0, the device always switch to the higher score SIM. If < 0, the network type and signal strength based auto switch is disabled. --> - <integer name="auto_data_switch_score_tolerance">-1</integer> + <integer name="auto_data_switch_score_tolerance">4000</integer> <java-symbol type="integer" name="auto_data_switch_score_tolerance" /> <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml index e82992b91783..7baaa6d590f2 100644 --- a/core/res/res/values/public-staging.xml +++ b/core/res/res/values/public-staging.xml @@ -116,7 +116,7 @@ <public name="adServiceTypes" /> <!-- @FlaggedApi("android.view.inputmethod.ime_switcher_revamp_api") --> <public name="languageSettingsActivity"/> - <!-- @FlaggedApi("android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM") --> + <!-- @FlaggedApi(android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM) --> <public name="dreamCategory"/> <!-- @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") @hide @SystemApi --> @@ -159,15 +159,15 @@ <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE) @hide @SystemApi --> - <public name="config_defaultOnDeviceIntelligenceService"></public> + <public name="config_defaultOnDeviceIntelligenceService" /> <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE) @hide @SystemApi --> - <public name="config_defaultOnDeviceSandboxedInferenceService"></public> + <public name="config_defaultOnDeviceSandboxedInferenceService" /> <!-- @FlaggedApi(android.app.ondeviceintelligence.flags.Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE_MODULE) @hide @SystemApi --> - <public name="config_defaultOnDeviceIntelligenceDeviceConfigNamespace"></public> + <public name="config_defaultOnDeviceIntelligenceDeviceConfigNamespace" /> </staging-public-group> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 68008e57094d..77cc6868bd58 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -366,6 +366,8 @@ <java-symbol type="bool" name="config_canSwitchToHeadlessSystemUser"/> <java-symbol type="bool" name="config_enableMultiUserUI"/> <java-symbol type="bool" name="config_enableMultipleAdmins"/> + <java-symbol type="bool" name="config_allowAlarmsOnStoppedUsers"/> + <java-symbol type="bool" name="config_showNotificationForBackgroundUserAlarms"/> <java-symbol type="bool" name="config_bootToHeadlessSystemUser"/> <java-symbol type="bool" name="config_omnipresentCommunalUser"/> <java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/> @@ -4364,10 +4366,6 @@ <java-symbol type="integer" name="config_unfoldTransitionHalfFoldedTimeout" /> <java-symbol type="array" name="config_perDeviceStateRotationLockDefaults" /> - - <java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" /> - <java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" /> - <java-symbol type="string" name="config_misprovisionedDeviceModel" /> <java-symbol type="string" name="config_misprovisionedBrandValue" /> @@ -5840,4 +5838,6 @@ <!-- Whether the device supports Wi-Fi USD feature. --> <java-symbol type="bool" name="config_deviceSupportsWifiUsd" /> + <java-symbol type="array" name="config_notificationDefaultUnsupportedAdjustments" /> + </resources> diff --git a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java index 44b2d90decf2..dfe7d0306905 100644 --- a/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java +++ b/core/tests/InputMethodCoreTests/src/android/view/inputmethod/InputMethodInfoTest.java @@ -26,7 +26,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.Bundle; import android.os.Parcel; -import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; @@ -124,7 +123,6 @@ public class InputMethodInfoTest { } @Test - @EnableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_CUSTOM_IME) public void testIsVirtualDeviceOnly() throws Exception { final InputMethodInfo imi = buildInputMethodForTest(R.xml.ime_meta_virtual_device_only); diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index 7be6950fb613..ca6ad6fae46e 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -2504,21 +2504,6 @@ public class NotificationTest { @Test @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_setProgressSegments() { - final List<Notification.ProgressStyle.Segment> segments = List.of( - new Notification.ProgressStyle.Segment(100).setColor(Color.WHITE), - new Notification.ProgressStyle.Segment(50).setColor(Color.RED), - new Notification.ProgressStyle.Segment(50).setColor(Color.BLUE) - ); - - final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); - progressStyle1.setProgressSegments(segments); - - assertThat(progressStyle1.getProgressSegments()).isEqualTo(segments); - } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) public void progressStyle_addProgressPoint_dropsNegativePoints() { // GIVEN final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); @@ -2547,21 +2532,6 @@ public class NotificationTest { @Test @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_setProgressPoints() { - final List<Notification.ProgressStyle.Point> points = List.of( - new Notification.ProgressStyle.Point(0).setColor(Color.WHITE), - new Notification.ProgressStyle.Point(50).setColor(Color.RED), - new Notification.ProgressStyle.Point(100).setColor(Color.BLUE) - ); - - final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); - progressStyle1.setProgressPoints(points); - - assertThat(progressStyle1.getProgressPoints()).isEqualTo(points); - } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) public void progressStyle_createProgressModel_ignoresPointsExceedingMax() { // GIVEN final Notification.ProgressStyle progressStyle = new Notification.ProgressStyle(); @@ -2703,58 +2673,11 @@ public class NotificationTest { @Test @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_setProgressIndeterminate() { - final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); - progressStyle1.setProgressIndeterminate(true); - assertThat(progressStyle1.isProgressIndeterminate()).isTrue(); - } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) public void progressStyle_styledByProgress_defaultValueTrue() { final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); assertThat(progressStyle1.isStyledByProgress()).isTrue(); } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_setStyledByProgress() { - final Notification.ProgressStyle progressStyle1 = new Notification.ProgressStyle(); - progressStyle1.setStyledByProgress(false); - assertThat(progressStyle1.isStyledByProgress()).isFalse(); - } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_point() { - final int id = 1; - final int position = 10; - final int color = Color.RED; - - final Notification.ProgressStyle.Point point = - new Notification.ProgressStyle.Point(position).setId(id).setColor(color); - - assertEquals(id, point.getId()); - assertEquals(position, point.getPosition()); - assertEquals(color, point.getColor()); - } - - @Test - @EnableFlags(Flags.FLAG_API_RICH_ONGOING) - public void progressStyle_segment() { - final int id = 1; - final int length = 100; - final int color = Color.RED; - - final Notification.ProgressStyle.Segment segment = - new Notification.ProgressStyle.Segment(length).setId(id).setColor(color); - - assertEquals(id, segment.getId()); - assertEquals(length, segment.getLength()); - assertEquals(color, segment.getColor()); - } - private void assertValid(Notification.Colors c) { // Assert that all colors are populated assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID); diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java index 133177935984..c58d53ba967c 100644 --- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java +++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java @@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.aMapWithSize; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.junit.Assert.assertThat; +import android.app.UiAutomation; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -38,6 +39,7 @@ import android.test.AndroidTestCase; import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import androidx.test.filters.Suppress; +import androidx.test.platform.app.InstrumentationRegistry; import java.util.HashMap; import java.util.List; @@ -447,4 +449,50 @@ public class SettingsProviderTest extends AndroidTestCase { r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, newName, null); } } + + @SmallTest + public void testCall_putOverrideConfig() throws Exception { + // The shell user is restricted to a set of allowlisted flags / namespaces that can be + // written. When an flag override is requested, the flag is rewritten to be in the form: + // device_config_overrides/namespace:flagname + // To avoid requiring allowlisting both the base flag and the override version, + // SettingsProvider will parse out the overridden flag and check if it has been allowlisted. + // This test verifies that this is properly handled for both the good case as well as when + // the overridden flag is not in the proper format by ensuring a SecurityException is not + // thrown since these flags have been allowlisted. + UiAutomation uiAutomation = + InstrumentationRegistry.getInstrumentation().getUiAutomation(); + uiAutomation.adoptShellPermissionIdentity(); + ContentResolver r = getContext().getContentResolver(); + String overridesNamespace = "device_config_overrides"; + String namespace = "namespace1"; + String flagName = "key1"; + String validFlag = overridesNamespace + "/" + namespace + ":" + flagName; + String invalidFlag1 = overridesNamespace + "/"; + String invalidFlag2 = overridesNamespace + "/" + namespace + ":"; + String invalidFlag3 = overridesNamespace + "/" + ":"; + String value = "value1"; + Bundle args = new Bundle(); + args.putString(Settings.NameValueTable.VALUE, value); + + try { + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, validFlag, args); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, invalidFlag1, + args); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, invalidFlag2, + args); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_PUT_CONFIG, invalidFlag3, + args); + } finally { + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, validFlag, + null); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, invalidFlag1, + null); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, invalidFlag2, + null); + r.call(Settings.Config.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, invalidFlag3, + null); + uiAutomation.dropShellPermissionIdentity(); + } + } } diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java index f87b6994900f..ee8d428d8370 100644 --- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java @@ -224,7 +224,7 @@ public class ContentCaptureSessionTest { } @Override - void flush(int reason) { + void internalFlush(int reason) { throw new UnsupportedOperationException("should not have been called"); } diff --git a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java index b42bcee77c67..a1d7f87614e4 100644 --- a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java +++ b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java @@ -263,7 +263,7 @@ public class MainContentCaptureSessionTest { session.mEvents = new ArrayList<>(Arrays.asList(EVENT)); session.mDirectServiceInterface = mMockContentCaptureDirectManager; - session.flush(REASON); + session.internalFlush(REASON); mTestableLooper.processAllMessages(); verifyZeroInteractions(mMockContentProtectionEventProcessor); @@ -280,7 +280,7 @@ public class MainContentCaptureSessionTest { session.mEvents = new ArrayList<>(Arrays.asList(EVENT)); session.mDirectServiceInterface = mMockContentCaptureDirectManager; - session.flush(REASON); + session.internalFlush(REASON); mTestableLooper.processAllMessages(); verifyZeroInteractions(mMockContentProtectionEventProcessor); @@ -298,7 +298,7 @@ public class MainContentCaptureSessionTest { session.mEvents = new ArrayList<>(Arrays.asList(EVENT)); session.mDirectServiceInterface = mMockContentCaptureDirectManager; - session.flush(REASON); + session.internalFlush(REASON); mTestableLooper.processAllMessages(); verifyZeroInteractions(mMockContentProtectionEventProcessor); @@ -316,7 +316,7 @@ public class MainContentCaptureSessionTest { session.mEvents = new ArrayList<>(Arrays.asList(EVENT)); session.mDirectServiceInterface = mMockContentCaptureDirectManager; - session.flush(REASON); + session.internalFlush(REASON); mTestableLooper.processAllMessages(); verifyZeroInteractions(mMockContentProtectionEventProcessor); @@ -499,6 +499,57 @@ public class MainContentCaptureSessionTest { assertThat(session.mEventProcessQueue).hasSize(1); } + @Test + public void notifyContentCaptureEvents_beforeSessionPerformStart() throws RemoteException { + ContentCaptureOptions options = + createOptions( + /* enableContentCaptureReceiver= */ true, + /* enableContentProtectionReceiver= */ true); + MainContentCaptureSession session = createSession(options); + session.mContentCaptureHandler = null; + session.mDirectServiceInterface = null; + + notifyContentCaptureEvents(session); + mTestableLooper.processAllMessages(); + + assertThat(session.mEvents).isNull(); + assertThat(session.mEventProcessQueue).hasSize(7); // 5 view events + 2 view tree events + } + + @Test + public void notifyViewAppeared_beforeSessionPerformStart() throws RemoteException { + ContentCaptureOptions options = + createOptions( + /* enableContentCaptureReceiver= */ true, + /* enableContentProtectionReceiver= */ true); + MainContentCaptureSession session = createSession(options); + session.mContentCaptureHandler = null; + session.mDirectServiceInterface = null; + + View view = prepareView(session); + session.notifyViewAppeared(session.newViewStructure(view)); + + assertThat(session.mEvents).isNull(); + assertThat(session.mEventProcessQueue).hasSize(1); + } + + @Test + public void flush_beforeSessionPerformStart() throws Exception { + ContentCaptureOptions options = + createOptions( + /* enableContentCaptureReceiver= */ true, + /* enableContentProtectionReceiver= */ true); + MainContentCaptureSession session = createSession(options); + session.mEvents = new ArrayList<>(Arrays.asList(EVENT)); + session.mContentCaptureHandler = null; + session.mDirectServiceInterface = null; + + session.internalFlush(REASON); + + assertThat(session.mEvents).hasSize(1); + assertThat(session.mEventProcessQueue).isEmpty(); + } + /** Simulates the regular content capture events sequence. */ private void notifyContentCaptureEvents(final MainContentCaptureSession session) { final ArrayList<Object> events = new ArrayList<>( @@ -561,8 +612,8 @@ public class MainContentCaptureSessionTest { sStrippedContext, manager, testHandler, - testHandler, mMockSystemServerInterface); + session.mContentCaptureHandler = testHandler; session.mComponentName = COMPONENT_NAME; return session; } diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 906c71d9caca..1c34e0d54908 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -66,12 +66,6 @@ public final class BLASTBufferQueue { } /** Create a new connection with the surface flinger. */ - public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height, - @PixelFormat.Format int format) { - this(name, true /* updateDestinationFrame */); - update(sc, width, height, format); - } - public BLASTBufferQueue(String name, boolean updateDestinationFrame) { mNativeObject = nativeCreate(name, updateDestinationFrame); } diff --git a/graphics/java/android/graphics/OWNERS b/graphics/java/android/graphics/OWNERS index ef8d26cc65b9..1ea197658f93 100644 --- a/graphics/java/android/graphics/OWNERS +++ b/graphics/java/android/graphics/OWNERS @@ -2,10 +2,10 @@ romainguy@google.com jreck@google.com -njawad@google.com sumir@google.com djsollen@google.com -scroggo@google.com +alecmouri@google.com +sallyqi@google.com per-file BLASTBufferQueue.java = file:/services/core/java/com/android/server/wm/OWNERS per-file FontFamily.java = file:fonts/OWNERS diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index e6c652c14c71..5e93f8db9388 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -20,6 +20,7 @@ import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MG import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.content.Context; import android.hardware.security.keymint.EcCurve; import android.hardware.security.keymint.KeyParameter; @@ -732,6 +733,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } + @RequiresPermission(value = android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, + conditional = true) private void addAttestationParameters(@NonNull List<KeyParameter> params) throws ProviderException, IllegalArgumentException, DeviceIdAttestationException { byte[] challenge = mSpec.getAttestationChallenge(); @@ -824,7 +827,13 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato break; } case AttestationUtils.ID_TYPE_MEID: { - final String meid = telephonyService.getMeid(0); + String meid; + try { + meid = telephonyService.getMeid(0); + } catch (UnsupportedOperationException e) { + Log.e(TAG, "Unable to retrieve MEID", e); + meid = null; + } if (meid == null) { throw new DeviceIdAttestationException("Unable to retrieve MEID"); } diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig index 73e7223a3aea..b10b099c970b 100644 --- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig +++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig @@ -13,13 +13,6 @@ flag { } flag { - name: "enable_split_contextual" - namespace: "multitasking" - description: "Enables invoking split contextually" - bug: "276361926" -} - -flag { name: "enable_taskbar_navbar_unification" namespace: "multitasking" description: "Enables taskbar / navbar unification" diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt index c62d2a06bad5..90ea7d35015e 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt @@ -34,7 +34,6 @@ import com.android.internal.protolog.ProtoLog import com.android.internal.statusbar.IStatusBarService import com.android.wm.shell.Flags import com.android.wm.shell.ShellTaskOrganizer -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.Bubbles.SysuiProxy import com.android.wm.shell.bubbles.properties.ProdBubbleProperties import com.android.wm.shell.bubbles.storage.BubblePersistentRepository @@ -44,6 +43,7 @@ import com.android.wm.shell.common.DisplayInsetsController import com.android.wm.shell.common.FloatingContentCoordinator import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.common.TaskStackListenerImpl +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.draganddrop.DragAndDropController import com.android.wm.shell.shared.TransactionPool import com.android.wm.shell.shared.bubbles.BubbleBarLocation diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt index ab2e552c7a3d..a7eebd6159e4 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt @@ -36,10 +36,10 @@ import com.android.internal.protolog.ProtoLog import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.Flags import com.android.wm.shell.R -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.Bubbles.SysuiProxy import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix import com.android.wm.shell.common.FloatingContentCoordinator +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt index 3043e2bcb0be..a83327bbadee 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleViewInfoTaskTest.kt @@ -35,7 +35,6 @@ import com.android.internal.protolog.ProtoLog import com.android.internal.statusbar.IStatusBarService import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.ShellTaskOrganizer -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.properties.BubbleProperties import com.android.wm.shell.bubbles.storage.BubblePersistentRepository import com.android.wm.shell.common.DisplayController @@ -44,6 +43,7 @@ import com.android.wm.shell.common.DisplayInsetsController import com.android.wm.shell.common.FloatingContentCoordinator import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.common.TaskStackListenerImpl +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.shared.TransactionPool import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt index bcaa63bfad36..750178678785 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt @@ -22,9 +22,9 @@ import android.content.res.Resources import android.view.LayoutInflater import com.android.internal.logging.testing.UiEventLoggerFake import com.android.wm.shell.R -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.BubbleViewInfoTask.BubbleViewInfo import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView +import com.android.wm.shell.common.TestShellExecutor import com.google.common.util.concurrent.MoreExecutors.directExecutor /** Helper to create a [Bubble] instance */ diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt index c45f6903c2e1..9e58b5be9d0d 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelperTest.kt @@ -36,7 +36,6 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.protolog.ProtoLog -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.Bubble import com.android.wm.shell.bubbles.BubbleExpandedViewManager import com.android.wm.shell.bubbles.BubbleLogger @@ -46,6 +45,7 @@ import com.android.wm.shell.bubbles.BubbleTaskView import com.android.wm.shell.bubbles.DeviceConfig import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager import com.android.wm.shell.bubbles.FakeBubbleFactory +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.taskview.TaskView import com.android.wm.shell.taskview.TaskViewTaskController import com.google.common.truth.Truth.assertThat @@ -290,11 +290,10 @@ class BubbleBarAnimationHelperTest { assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue() - val bbevBottom = bbev.contentBottomOnScreen + bubblePositioner.insets.top activityScenario.onActivity { // notify that the IME top coordinate is greater than the bottom of the expanded view. // there's no overlap so it should not be clipped. - animationHelper.onImeTopChanged(bbevBottom * 2) + animationHelper.onImeTopChanged(bbev.contentBottomOnScreen * 2) } val outline = Outline() bbev.outlineProvider.getOutline(bbev, outline) diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt index bfc798bb9c79..fbbcff2dee92 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt @@ -33,7 +33,6 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.protolog.ProtoLog import com.android.wm.shell.R -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.Bubble import com.android.wm.shell.bubbles.BubbleExpandedViewManager import com.android.wm.shell.bubbles.BubbleLogger @@ -44,6 +43,7 @@ import com.android.wm.shell.bubbles.DeviceConfig import com.android.wm.shell.bubbles.FakeBubbleExpandedViewManager import com.android.wm.shell.bubbles.RegionSamplingProvider import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.shared.handles.RegionSamplingHelper import com.android.wm.shell.taskview.TaskView import com.android.wm.shell.taskview.TaskViewTaskController diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt index 9b1645e9534c..5c5dde7da351 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt @@ -36,7 +36,6 @@ import com.android.internal.protolog.ProtoLog import com.android.internal.statusbar.IStatusBarService import com.android.wm.shell.R import com.android.wm.shell.ShellTaskOrganizer -import com.android.wm.shell.TestShellExecutor import com.android.wm.shell.bubbles.Bubble import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.bubbles.BubbleData @@ -58,6 +57,7 @@ import com.android.wm.shell.common.DisplayInsetsController import com.android.wm.shell.common.FloatingContentCoordinator import com.android.wm.shell.common.SyncTransactionQueue import com.android.wm.shell.common.TaskStackListenerImpl +import com.android.wm.shell.common.TestShellExecutor import com.android.wm.shell.shared.TransactionPool import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils import com.android.wm.shell.shared.bubbles.BubbleBarLocation diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/TestShellExecutor.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/common/TestShellExecutor.kt index ef8e71c2590b..6b549b42cdcd 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/TestShellExecutor.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/common/TestShellExecutor.kt @@ -14,9 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell - -import com.android.wm.shell.common.ShellExecutor +package com.android.wm.shell.common /** * Simple implementation of [ShellExecutor] that collects all runnables and executes them diff --git a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_maximize_button_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_maximize_button_dark.xml index e5fe1b5431eb..83a3959ee2f9 100644 --- a/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_maximize_button_dark.xml +++ b/libs/WindowManager/Shell/res/drawable/decor_desktop_mode_maximize_button_dark.xml @@ -22,5 +22,6 @@ android:viewportWidth="960"> <path android:fillColor="@android:color/black" - android:pathData="M160,800Q127,800 103.5,776.5Q80,753 80,720L80,240Q80,207 103.5,183.5Q127,160 160,160L800,160Q833,160 856.5,183.5Q880,207 880,240L880,720Q880,753 856.5,776.5Q833,800 800,800L160,800ZM160,720L800,720Q800,720 800,720Q800,720 800,720L800,320L160,320L160,720Q160,720 160,720Q160,720 160,720Z"/> + android:pathData="M 244.79 796.408 C 222.79 796.408 203.79 788.74 187.79 773.408 C 172.457 757.408 164.79 738.408 164.79 716.408 L 164.79 236.408 C 164.79 214.408 172.457 195.741 187.79 180.408 C 203.79 164.408 222.79 156.408 244.79 156.408 L 724.79 156.408 C 746.79 156.408 765.458 164.408 780.79 180.408 C 796.79 195.741 804.79 214.408 804.79 236.408 L 804.79 716.408 C 804.79 738.408 796.79 757.408 780.79 773.408 C 765.458 788.74 746.79 796.408 724.79 796.408 Z M 244.79 716.408 L 724.79 716.408 L 724.79 236.408 L 244.79 236.408 Z M 244.79 236.408 L 244.79 716.408 Z" + /> </vector>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 6f18eda13caf..cf9c18b43a5e 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -23,7 +23,7 @@ <string name="pip_menu_title" msgid="5393619322111827096">"תפריט"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"תפריט \'תמונה בתוך תמונה\'"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> במצב תמונה בתוך תמונה"</string> - <string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש להקיש כדי לפתוח את ההגדרות ולהשבית את התכונה."</string> + <string name="pip_notification_message" msgid="8854051911700302620">"אם אינך רוצה שהתכונה הזו תשמש את <xliff:g id="NAME">%s</xliff:g>, יש ללחוץ כדי לפתוח את ההגדרות ולהשבית את התכונה."</string> <string name="pip_play" msgid="3496151081459417097">"הפעלה"</string> <string name="pip_pause" msgid="690688849510295232">"השהיה"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"אפשר לדלג אל הבא"</string> @@ -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> @@ -76,33 +76,33 @@ <string name="bubble_fullscreen_text" msgid="1006758103218086231">"הצגה במסך מלא"</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_manage" msgid="3460756219946517198">"יש ללחוץ על \'ניהול\' כדי להשבית את הבועות מהאפליקציה הזו"</string> <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"הבנתי"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"אין בועות מהזמן האחרון"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"בועות אחרונות ובועות שנסגרו יופיעו כאן"</string> <string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"צ\'אט בבועות"</string> - <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"שיחות חדשות מופיעות כסמלים בפינה התחתונה של המסך. אפשר להקיש כדי להרחיב אותן או לגרור כדי לסגור אותן."</string> + <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"שיחות חדשות מופיעות כסמלים בפינה התחתונה של המסך. אפשר ללחוץ כדי להרחיב אותן או לגרור כדי לסגור אותן."</string> <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"שליטה בבועות בכל זמן"</string> - <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"אפשר להקיש כאן כדי לקבוע אילו אפליקציות ושיחות יוכלו להופיע בבועות"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"אפשר ללחוץ כאן כדי לקבוע אילו אפליקציות ושיחות יוכלו להופיע בבועות"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string> <string name="bubble_shortcut_label" msgid="666269077944378311">"בועות"</string> <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"הצגת הבועות"</string> - <string name="restart_button_description" msgid="4564728020654658478">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש"</string> + <string name="restart_button_description" msgid="4564728020654658478">"כדי לראות טוב יותר יש ללחוץ ולהפעיל את האפליקציה הזו מחדש"</string> <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"אפשר לשנות את יחס הגובה-רוחב של האפליקציה הזו ב\'הגדרות\'"</string> <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"שינוי יחס גובה-רוחב"</string> - <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש"</string> - <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת"</string> - <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר להקיש כדי לסגור."</string> + <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר ללחוץ כדי לבצע התאמה מחדש"</string> + <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר ללחוץ כדי לחזור לגרסה הקודמת"</string> + <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר ללחוץ כדי לסגור."</string> <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"תפריט האפליקציה נמצא כאן"</string> <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="2523468503353474095">"כדי לפתוח כמה אפליקציות יחד, צריך לעבור למצב תצוגה למחשב"</string> <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"אפשר לחזור למסך מלא בכל שלב מתפריט האפליקציה"</string> <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"רוצה לראות ולעשות יותר?"</string> <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"צריך לגרור אפליקציה אחרת כדי להשתמש במסך המפוצל"</string> - <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"צריך להקיש הקשה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש"</string> + <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"צריך ללחוץ לחיצה כפולה מחוץ לאפליקציה כדי למקם אותה מחדש"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"מרחיבים כדי לקבל מידע נוסף."</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"להפעיל מחדש לתצוגה טובה יותר?"</string> @@ -110,7 +110,7 @@ <string name="letterbox_restart_cancel" msgid="1342209132692537805">"ביטול"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"הפעלה מחדש"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"לא להציג שוב"</string> - <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"אפשר להקיש הקשה כפולה כדי\nלהעביר את האפליקציה למקום אחר"</string> + <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"אפשר ללחוץ לחיצה כפולה כדי\nלהעביר את האפליקציה למקום אחר"</string> <string name="maximize_button_text" msgid="1650859196290301963">"הגדלה"</string> <string name="minimize_button_text" msgid="271592547935841753">"מזעור"</string> <string name="close_button_text" msgid="2913281996024033299">"סגירה"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 9e0f107f7e55..abc4d08cd3ca 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -25,7 +25,7 @@ <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> చిత్రంలో చిత్రం రూపంలో ఉంది"</string> <string name="pip_notification_message" msgid="8854051911700302620">"<xliff:g id="NAME">%s</xliff:g> ఈ లక్షణాన్ని ఉపయోగించకూడదు అని మీరు అనుకుంటే, సెట్టింగ్లను తెరవడానికి ట్యాప్ చేసి, దీన్ని ఆఫ్ చేయండి."</string> <string name="pip_play" msgid="3496151081459417097">"ప్లే చేయి"</string> - <string name="pip_pause" msgid="690688849510295232">"పాజ్ చేయి"</string> + <string name="pip_pause" msgid="690688849510295232">"పాజ్ చేయండి"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"దాటవేసి తర్వాత దానికి వెళ్లు"</string> <string name="pip_skip_to_prev" msgid="7172158111196394092">"దాటవేసి మునుపటి దానికి వెళ్లు"</string> <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"సైజ్ మార్చు"</string> diff --git a/libs/WindowManager/Shell/shared/Android.bp b/libs/WindowManager/Shell/shared/Android.bp index c3ee0f76f550..d7669ed5cf34 100644 --- a/libs/WindowManager/Shell/shared/Android.bp +++ b/libs/WindowManager/Shell/shared/Android.bp @@ -56,6 +56,7 @@ android_library { static_libs: [ "androidx.core_core-animation", "androidx.dynamicanimation_dynamicanimation", + "com_android_wm_shell_flags_lib", "jsr330", ], kotlincflags: ["-Xjvm-default=all"], diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java index e033f673d07d..840de2c86f92 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TransitionUtil.java @@ -40,7 +40,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityManager; -import android.app.TaskInfo; import android.app.WindowConfiguration; import android.graphics.Rect; import android.util.ArrayMap; @@ -57,6 +56,9 @@ public class TransitionUtil { /** Flag applied to a transition change to identify it as a divider bar for animation. */ public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM; + /** Flag applied to a transition change to identify it as a desktop wallpaper activity. */ + public static final int FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY = FLAG_FIRST_CUSTOM << 1; + /** @return true if the transition was triggered by opening something vs closing something */ public static boolean isOpeningType(@WindowManager.TransitionType int type) { return type == TRANSIT_OPEN diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleAnythingFlagHelper.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleAnythingFlagHelper.java new file mode 100644 index 000000000000..e1f1d0c32eb0 --- /dev/null +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/bubbles/BubbleAnythingFlagHelper.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.shared.bubbles; + +import com.android.wm.shell.Flags; + +/** + * Bubble anything has some dependent flags, this class simplifies the checks. + * (TODO: b/389737359 - remove this when the feature is launched). + */ +public class BubbleAnythingFlagHelper { + + private BubbleAnythingFlagHelper() {} + + /** Whether creating any bubble or the overall bubble anything feature is enabled. */ + public static boolean enableCreateAnyBubble() { + return enableBubbleAnything() || Flags.enableCreateAnyBubble(); + } + + /** + * Whether creating any bubble and transforming to fullscreen, or the overall bubble anything + * feature is enabled. + */ + public static boolean enableBubbleToFullscreen() { + return enableBubbleAnything() + || (Flags.enableBubbleToFullscreen() + && Flags.enableCreateAnyBubble()); + } + + /** Whether the overall bubble anything feature is enabled. */ + public static boolean enableBubbleAnything() { + return Flags.enableBubbleAnything(); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java index e073b02dc630..ac5b9c9866ed 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java @@ -674,9 +674,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView if (mTaskView != null) { mTaskView.getBoundsOnScreen(mTempBounds); } - // return the bottom of the content rect, adjusted for insets so the result is in screen - // coordinate - return mTempBounds.bottom + mPositioner.getInsets().top; + return mTempBounds.bottom; } /** Update the amount by which to clip the expanded view at the bottom. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ComponentUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ComponentUtils.kt index 67592e60e954..0d0bc9be72b3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ComponentUtils.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ComponentUtils.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.common import android.app.PendingIntent +import android.app.TaskInfo import android.content.ComponentName import android.content.Intent import com.android.wm.shell.ShellTaskOrganizer @@ -34,7 +35,11 @@ object ComponentUtils { /** Retrieves the package name from a [taskId]. */ @JvmStatic fun getPackageName(taskId: Int, taskOrganizer: ShellTaskOrganizer): String? { - val taskInfo = taskOrganizer.getRunningTaskInfo(taskId) - return getPackageName(taskInfo?.baseIntent) + val taskInfo = taskOrganizer.getRunningTaskInfo(taskId) ?: return null + return getPackageName(taskInfo) } + + /** Retrieves the package name from a [TaskInfo]. */ + @JvmStatic + fun getPackageName(taskInfo: TaskInfo): String? = getPackageName(taskInfo.baseIntent) } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculator.kt new file mode 100644 index 000000000000..a13ad20f8c05 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculator.kt @@ -0,0 +1,86 @@ +/* + * 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.wm.shell.common + +import android.graphics.PointF +import android.graphics.Rect +import android.graphics.RectF + +/** + * Utility class for calculating bounds during multi-display drag operations. + * + * This class provides helper functions to perform bounds calculation during window drag. + */ +object MultiDisplayDragMoveBoundsCalculator { + /** + * Calculates the global DP bounds of a window being dragged across displays. + * + * @param startDisplayLayout The DisplayLayout object of the display where the drag started. + * @param repositionStartPoint The starting position of the drag (in pixels), relative to the + * display where the drag started. + * @param boundsAtDragStart The initial bounds of the window (in pixels), relative to the + * display where the drag started. + * @param currentDisplayLayout The DisplayLayout object of the display where the pointer is + * currently located. + * @param x The current x-coordinate of the drag pointer (in pixels). + * @param y The current y-coordinate of the drag pointer (in pixels). + * @return A RectF object representing the calculated global DP bounds of the window. + */ + fun calculateGlobalDpBoundsForDrag( + startDisplayLayout: DisplayLayout, + repositionStartPoint: PointF, + boundsAtDragStart: Rect, + currentDisplayLayout: DisplayLayout, + x: Float, + y: Float, + ): RectF { + // Convert all pixel values to DP. + val startCursorDp = + startDisplayLayout.localPxToGlobalDp(repositionStartPoint.x, repositionStartPoint.y) + val currentCursorDp = currentDisplayLayout.localPxToGlobalDp(x, y) + val startLeftTopDp = + startDisplayLayout.localPxToGlobalDp(boundsAtDragStart.left, boundsAtDragStart.top) + val widthDp = startDisplayLayout.pxToDp(boundsAtDragStart.width()) + val heightDp = startDisplayLayout.pxToDp(boundsAtDragStart.height()) + + // Calculate DP bounds based on pointer movement delta. + val currentLeftDp = startLeftTopDp.x + (currentCursorDp.x - startCursorDp.x) + val currentTopDp = startLeftTopDp.y + (currentCursorDp.y - startCursorDp.y) + val currentRightDp = currentLeftDp + widthDp + val currentBottomDp = currentTopDp + heightDp + + return RectF(currentLeftDp, currentTopDp, currentRightDp, currentBottomDp) + } + + /** + * Converts global DP bounds to local pixel bounds for a specific display. + * + * @param rectDp The global DP bounds to convert. + * @param displayLayout The DisplayLayout representing the display to convert the bounds to. + * @return A Rect object representing the local pixel bounds on the specified display. + */ + fun convertGlobalDpToLocalPxForRect(rectDp: RectF, displayLayout: DisplayLayout): Rect { + val leftTopPxDisplay = displayLayout.globalDpToLocalPx(rectDp.left, rectDp.top) + val rightBottomPxDisplay = displayLayout.globalDpToLocalPx(rectDp.right, rectDp.bottom) + return Rect( + leftTopPxDisplay.x.toInt(), + leftTopPxDisplay.y.toInt(), + rightBottomPxDisplay.x.toInt(), + rightBottomPxDisplay.y.toInt(), + ) + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index ac510f89b905..e8add56619c4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -946,7 +946,8 @@ public abstract class WMShellModule { FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler ) { if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) { return Optional.empty(); @@ -962,7 +963,7 @@ public abstract class WMShellModule { desktopTasksLimiter, appHandleEducationController, appToWebEducationController, windowDecorCaptionHandleRepository, activityOrientationChangeHandler, focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger, - taskResourceLoader)); + taskResourceLoader, recentsTransitionHandler)); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt index cdfa14bbc4e2..9b9988457808 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeShellCommandHandler.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.desktopmode +import com.android.window.flags.Flags import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource.UNKNOWN import com.android.wm.shell.sysui.ShellCommandHandler import java.io.PrintWriter @@ -26,35 +27,28 @@ class DesktopModeShellCommandHandler(private val controller: DesktopTasksControl override fun onShellCommand(args: Array<String>, pw: PrintWriter): Boolean = when (args[0]) { - "moveToDesktop" -> { - if (!runMoveToDesktop(args, pw)) { - pw.println("Task not found. Please enter a valid taskId.") - false - } else { - true - } - } - "moveToNextDisplay" -> { - if (!runMoveToNextDisplay(args, pw)) { - pw.println("Task not found. Please enter a valid taskId.") - false - } else { - true - } - } + "moveTaskToDesk" -> runMoveTaskToDesk(args, pw) + "moveToNextDisplay" -> runMoveToNextDisplay(args, pw) + "createDesk" -> runCreateDesk(args, pw) + "activateDesk" -> runActivateDesk(args, pw) + "removeDesk" -> runRemoveDesk(args, pw) + "removeAllDesks" -> runRemoveAllDesks(args, pw) + "moveTaskToFront" -> runMoveTaskToFront(args, pw) + "moveTaskOutOfDesk" -> runMoveTaskOutOfDesk(args, pw) + "canCreateDesk" -> runCanCreateDesk(args, pw) + "getActiveDeskId" -> runGetActiveDeskId(args, pw) else -> { pw.println("Invalid command: ${args[0]}") false } } - private fun runMoveToDesktop(args: Array<String>, pw: PrintWriter): Boolean { + private fun runMoveTaskToDesk(args: Array<String>, pw: PrintWriter): Boolean { if (args.size < 2) { // First argument is the action name. pw.println("Error: task id should be provided as arguments") return false } - val taskId = try { args[1].toInt() @@ -62,7 +56,22 @@ class DesktopModeShellCommandHandler(private val controller: DesktopTasksControl pw.println("Error: task id should be an integer") return false } - return controller.moveTaskToDesktop(taskId, transitionSource = UNKNOWN) + if (!Flags.enableMultipleDesktopsBackend()) { + return controller.moveTaskToDesktop(taskId, transitionSource = UNKNOWN) + } + if (args.size < 3) { + pw.println("Error: desk id should be provided as arguments") + return false + } + val deskId = + try { + args[2].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: desk id should be an integer") + return false + } + pw.println("Not implemented.") + return false } private fun runMoveToNextDisplay(args: Array<String>, pw: PrintWriter): Boolean { @@ -84,10 +93,184 @@ class DesktopModeShellCommandHandler(private val controller: DesktopTasksControl return true } + private fun runCreateDesk(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: desk id should be provided as arguments") + return false + } + val displayId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: display id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runActivateDesk(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: desk id should be provided as arguments") + return false + } + val deskId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: desk id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runRemoveDesk(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: desk id should be provided as arguments") + return false + } + val deskId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: desk id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runRemoveAllDesks(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runMoveTaskToFront(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: task id should be provided as arguments") + return false + } + val taskId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: task id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runMoveTaskOutOfDesk(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: task id should be provided as arguments") + return false + } + val taskId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: task id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runCanCreateDesk(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + val displayId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: display id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + + private fun runGetActiveDeskId(args: Array<String>, pw: PrintWriter): Boolean { + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("Not supported.") + return false + } + if (args.size < 2) { + // First argument is the action name. + pw.println("Error: task id should be provided as arguments") + return false + } + val displayId = + try { + args[1].toInt() + } catch (e: NumberFormatException) { + pw.println("Error: display id should be an integer") + return false + } + pw.println("Not implemented.") + return false + } + override fun printShellCommandHelp(pw: PrintWriter, prefix: String) { - pw.println("$prefix moveToDesktop <taskId> ") - pw.println("$prefix Move a task with given id to desktop mode.") - pw.println("$prefix moveToNextDisplay <taskId> ") + if (!Flags.enableMultipleDesktopsBackend()) { + pw.println("$prefix moveTaskToDesk <taskId> ") + pw.println("$prefix Move a task with given id to desktop mode.") + pw.println("$prefix moveToNextDisplay <taskId> ") + pw.println("$prefix Move a task with given id to next display.") + return + } + pw.println("$prefix moveTaskToDesk <taskId> <deskId>") + pw.println("$prefix Move a task with given id to the given desk and activate it.") + pw.println("$prefix moveToNextDisplay <taskId>") pw.println("$prefix Move a task with given id to next display.") + pw.println("$prefix createDesk <displayId>") + pw.println("$prefix Creates a desk on the given display.") + pw.println("$prefix activateDesk <deskId>") + pw.println("$prefix Activates the given desk.") + pw.println("$prefix removeDesk <deskId> ") + pw.println("$prefix Removes the given desk and all of its windows.") + pw.println("$prefix removeAllDesks") + pw.println("$prefix Removes all the desks and their windows across all displays") + pw.println("$prefix moveTaskToFront <taskId>") + pw.println("$prefix Moves a task in front of its siblings.") + pw.println("$prefix moveTaskOutOfDesk <taskId>") + pw.println("$prefix Moves the given desktop task out of the desk into fullscreen mode.") + pw.println("$prefix canCreateDesk <displayId>") + pw.println("$prefix Whether creating a new desk in the given display is allowed.") + pw.println("$prefix getActivateDeskId <displayId>") + pw.println("$prefix Print the id of the active desk in the given display.") } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index f38957e48dbf..91e06300f1b0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -35,6 +35,7 @@ import android.graphics.PointF import android.graphics.Rect import android.graphics.Region import android.os.Binder +import android.os.Bundle import android.os.Handler import android.os.IBinder import android.os.SystemProperties @@ -884,6 +885,36 @@ class DesktopTasksController( } /** + * Start an intent through a launch transition for starting tasks whose transition does not get + * handled by [handleRequest] + */ + fun startLaunchIntentTransition(intent: Intent, options: Bundle, displayId: Int) { + val wct = WindowContainerTransaction() + val displayLayout = displayController.getDisplayLayout(displayId) ?: return + val bounds = calculateDefaultDesktopTaskBounds(displayLayout) + if (DesktopModeFlags.ENABLE_CASCADING_WINDOWS.isTrue) { + cascadeWindow(bounds, displayLayout, displayId) + } + val pendingIntent = + PendingIntent.getActivity( + context, + /* requestCode= */ 0, + intent, + PendingIntent.FLAG_IMMUTABLE, + ) + val ops = + ActivityOptions.fromBundle(options).apply { + launchWindowingMode = WINDOWING_MODE_FREEFORM + pendingIntentBackgroundActivityStartMode = + ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS + launchBounds = bounds + } + + wct.sendPendingIntent(pendingIntent, intent, ops.toBundle()) + startLaunchTransition(TRANSIT_OPEN, wct, launchingTaskId = null) + } + + /** * Move [task] to display with [displayId]. * * No-op if task is already on that display per [RunningTaskInfo.displayId]. @@ -2425,6 +2456,25 @@ class DesktopTasksController( // Update task bounds so that the task position will match the position of its leash val wct = WindowContainerTransaction() wct.setBounds(taskInfo.token, destinationBounds) + + // TODO: b/362720497 - reparent to a specific desk within the target display. + // Reparent task if it has been moved to a new display. + if (Flags.enableConnectedDisplaysWindowDrag()) { + val newDisplayId = motionEvent.getDisplayId() + if (newDisplayId != taskInfo.getDisplayId()) { + val displayAreaInfo = + rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(newDisplayId) + if (displayAreaInfo == null) { + logW( + "Task reparent cannot find DisplayAreaInfo for displayId=%d", + newDisplayId, + ) + } else { + wct.reparent(taskInfo.token, displayAreaInfo.token, /* onTop= */ true) + } + } + } + transitions.startTransition(TRANSIT_CHANGE, wct, null) releaseVisualIndicator() @@ -2885,6 +2935,12 @@ class DesktopTasksController( c.moveToNextDisplay(taskId) } } + + override fun startLaunchIntentTransition(intent: Intent, options: Bundle, displayId: Int) { + executeRemoteCallWithTaskPermission(controller, "startLaunchIntentTransition") { c -> + c.startLaunchIntentTransition(intent, options, displayId) + } + } } private fun logV(msg: String, vararg arguments: Any?) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl index fa383cb55118..54f031293486 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/IDesktopMode.aidl @@ -17,6 +17,8 @@ package com.android.wm.shell.desktopmode; import android.app.ActivityManager.RunningTaskInfo; +import android.content.Intent; +import android.os.Bundle; import android.window.RemoteTransition; import com.android.wm.shell.desktopmode.IDesktopTaskListener; import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource; @@ -61,4 +63,7 @@ interface IDesktopMode { /** Move a task with given `taskId` to external display */ void moveToExternalDisplay(int taskId); + + /** Start a transition when launching an intent in desktop mode */ + void startLaunchIntentTransition(in Intent intent, in Bundle options, in int displayId); }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl index 32c79a2d02de..8cdb8c4512a9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentsAnimationRunner.aidl @@ -17,9 +17,10 @@ package com.android.wm.shell.recents; import android.graphics.Rect; +import android.os.Bundle; import android.view.RemoteAnimationTarget; import android.window.TaskSnapshot; -import android.os.Bundle; +import android.window.TransitionInfo; import com.android.wm.shell.recents.IRecentsAnimationController; @@ -57,7 +58,8 @@ oneway interface IRecentsAnimationRunner { */ void onAnimationStart(in IRecentsAnimationController controller, in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers, - in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras) = 2; + in Rect homeContentInsets, in Rect minimizedHomeBounds, in Bundle extras, + in TransitionInfo info) = 2; /** * Called when the task of an activity that has been started while the recents animation diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java index 975b65023f20..0182588398a4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java @@ -54,7 +54,6 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.ProtoLog; -import com.android.launcher3.Flags; import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; @@ -553,9 +552,7 @@ public class RecentTasksController implements TaskStackListenerCallback, groupedTasks.add(GroupedTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo, mTaskSplitBoundsMap.get(pairedTaskId))); } else { - if ( - Flags.enableUseTopVisibleActivityForExcludeFromRecentTask() - && isWallpaperTask(taskInfo)) { + if (isWallpaperTask(taskInfo)) { // Don't add the wallpaper task as an entry in grouped tasks continue; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index db582aa30f6a..aeccd86e122c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -587,7 +587,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), new RemoteAnimationTarget[0], - new Rect(0, 0, 0, 0), new Rect(), new Bundle()); + new Rect(0, 0, 0, 0), new Rect(), new Bundle(), + null); for (int i = 0; i < mStateListeners.size(); i++) { mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING); } @@ -818,7 +819,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler, mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]), wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]), - new Rect(0, 0, 0, 0), new Rect(), b); + new Rect(0, 0, 0, 0), new Rect(), b, info); for (int i = 0; i < mStateListeners.size(); i++) { mStateListeners.get(i).onTransitionStateChanged(TRANSITION_STATE_ANIMATING); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java index 6d01e247b48d..e04682a4b86f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/FocusTransitionObserver.java @@ -17,6 +17,8 @@ package com.android.wm.shell.transition; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.Display.INVALID_DISPLAY; +import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; @@ -66,36 +68,45 @@ public class FocusTransitionObserver { if (!enableDisplayFocusInShellTransitions()) { return; } + final SparseArray<RunningTaskInfo> lastTransitionFocusedTasks = + mFocusedTaskOnDisplay.clone(); + final List<TransitionInfo.Change> changes = info.getChanges(); for (int i = changes.size() - 1; i >= 0; i--) { final TransitionInfo.Change change = changes.get(i); final RunningTaskInfo task = change.getTaskInfo(); - if (task != null - && (change.hasFlags(FLAG_MOVED_TO_TOP) || change.getMode() == TRANSIT_OPEN)) { - final RunningTaskInfo lastFocusedTaskOnDisplay = - mFocusedTaskOnDisplay.get(task.displayId); - if (lastFocusedTaskOnDisplay != null) { - mTmpTasksToBeNotified.add(lastFocusedTaskOnDisplay); + if (task != null) { + if (change.hasFlags(FLAG_MOVED_TO_TOP) || change.getMode() == TRANSIT_OPEN) { + updateFocusedTaskPerDisplay(task, task.displayId); + } else { + // Update focus assuming that any task moved to another display is focused in + // the new display. + // TODO(sahok): remove this logic when b/388665104 is fixed + final boolean isBeyondDisplay = change.getStartDisplayId() != INVALID_DISPLAY + && change.getEndDisplayId() != INVALID_DISPLAY + && change.getStartDisplayId() != change.getEndDisplayId(); + + RunningTaskInfo lastTransitionFocusedTaskOnStartDisplay = + lastTransitionFocusedTasks.get(change.getStartDisplayId()); + final boolean isLastTransitionFocused = + lastTransitionFocusedTaskOnStartDisplay != null + && task.taskId + == lastTransitionFocusedTaskOnStartDisplay.taskId; + if (change.getMode() == TRANSIT_CHANGE && isBeyondDisplay + && isLastTransitionFocused) { + // The task have moved to another display and keeps its focus. + // MOVE_TO_TOP is not reported but we need to update the focused task in + // the end display. + updateFocusedTaskPerDisplay(task, change.getEndDisplayId()); + } } - mTmpTasksToBeNotified.add(task); - mFocusedTaskOnDisplay.put(task.displayId, task); } + if (change.hasFlags(FLAG_IS_DISPLAY) && change.hasFlags(FLAG_MOVED_TO_TOP)) { if (mFocusedDisplayId != change.getEndDisplayId()) { - final RunningTaskInfo lastGloballyFocusedTask = - mFocusedTaskOnDisplay.get(mFocusedDisplayId); - if (lastGloballyFocusedTask != null) { - mTmpTasksToBeNotified.add(lastGloballyFocusedTask); - } - mFocusedDisplayId = change.getEndDisplayId(); - notifyFocusedDisplayChanged(); - final RunningTaskInfo currentGloballyFocusedTask = - mFocusedTaskOnDisplay.get(mFocusedDisplayId); - if (currentGloballyFocusedTask != null) { - mTmpTasksToBeNotified.add(currentGloballyFocusedTask); - } + updateFocusedDisplay(change.getEndDisplayId()); } } } @@ -103,6 +114,31 @@ public class FocusTransitionObserver { mTmpTasksToBeNotified.clear(); } + private void updateFocusedTaskPerDisplay(RunningTaskInfo task, int displayId) { + final RunningTaskInfo lastFocusedTaskOnDisplay = + mFocusedTaskOnDisplay.get(displayId); + if (lastFocusedTaskOnDisplay != null) { + mTmpTasksToBeNotified.add(lastFocusedTaskOnDisplay); + } + mTmpTasksToBeNotified.add(task); + mFocusedTaskOnDisplay.put(displayId, task); + } + + private void updateFocusedDisplay(int endDisplayId) { + final RunningTaskInfo lastGloballyFocusedTask = + mFocusedTaskOnDisplay.get(mFocusedDisplayId); + if (lastGloballyFocusedTask != null) { + mTmpTasksToBeNotified.add(lastGloballyFocusedTask); + } + mFocusedDisplayId = endDisplayId; + notifyFocusedDisplayChanged(); + final RunningTaskInfo currentGloballyFocusedTask = + mFocusedTaskOnDisplay.get(mFocusedDisplayId); + if (currentGloballyFocusedTask != null) { + mTmpTasksToBeNotified.add(currentGloballyFocusedTask); + } + } + /** * Sets the focus transition listener that receives any transitions resulting in focus switch. * This is for calls from outside the Shell, within the host process. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index d5929f010e02..abfb41bb513a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -39,6 +39,7 @@ import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPI import static com.android.systemui.shared.Flags.returnAnimationFrameworkLongLived; import static com.android.window.flags.Flags.ensureWallpaperInTransitions; +import static com.android.wm.shell.shared.TransitionUtil.FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY; import static com.android.wm.shell.shared.TransitionUtil.isClosingType; import static com.android.wm.shell.shared.TransitionUtil.isOpeningType; @@ -84,6 +85,7 @@ import com.android.wm.shell.common.ExternalInterfaceBinder; import com.android.wm.shell.common.RemoteCallable; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes; +import com.android.wm.shell.desktopmode.DesktopWallpaperActivity; import com.android.wm.shell.keyguard.KeyguardTransitionHandler; import com.android.wm.shell.protolog.ShellProtoLogGroup; import com.android.wm.shell.shared.FocusTransitionListener; @@ -795,6 +797,14 @@ public class Transitions implements RemoteCallable<Transitions>, mReadyDuringSync.remove(active); } + // If any of the changes are on DesktopWallpaperActivity, add the flag to the change. + for (TransitionInfo.Change change : info.getChanges()) { + if (change.getTaskInfo() != null + && DesktopWallpaperActivity.isWallpaperTask(change.getTaskInfo())) { + change.setFlags(FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY); + } + } + final Track track = getOrCreateTrack(info.getTrack()); track.mReadyTransitions.add(active); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java index 67dae283345a..d6d393f2500c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java @@ -99,6 +99,7 @@ import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.apptoweb.AppToWebGenericLinksParser; import com.android.wm.shell.apptoweb.AssistContentRequester; +import com.android.wm.shell.common.ComponentUtils; import com.android.wm.shell.common.DisplayChangeController; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; @@ -126,6 +127,8 @@ import com.android.wm.shell.desktopmode.common.ToggleTaskSizeUtilsKt; import com.android.wm.shell.desktopmode.education.AppHandleEducationController; import com.android.wm.shell.desktopmode.education.AppToWebEducationController; import com.android.wm.shell.freeform.FreeformTaskTransitionStarter; +import com.android.wm.shell.recents.RecentsTransitionHandler; +import com.android.wm.shell.recents.RecentsTransitionStateListener; import com.android.wm.shell.shared.FocusTransitionListener; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; @@ -157,8 +160,10 @@ import kotlinx.coroutines.MainCoroutineDispatcher; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.function.Supplier; /** @@ -247,6 +252,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, private final DesktopModeEventLogger mDesktopModeEventLogger; private final DesktopModeUiEventLogger mDesktopModeUiEventLogger; private final WindowDecorTaskResourceLoader mTaskResourceLoader; + private final RecentsTransitionHandler mRecentsTransitionHandler; public DesktopModeWindowDecorViewModel( Context context, @@ -282,7 +288,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader) { + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler) { this( context, shellExecutor, @@ -323,7 +330,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger, - taskResourceLoader); + taskResourceLoader, + recentsTransitionHandler); } @VisibleForTesting @@ -367,7 +375,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, FocusTransitionObserver focusTransitionObserver, DesktopModeEventLogger desktopModeEventLogger, DesktopModeUiEventLogger desktopModeUiEventLogger, - WindowDecorTaskResourceLoader taskResourceLoader) { + WindowDecorTaskResourceLoader taskResourceLoader, + RecentsTransitionHandler recentsTransitionHandler) { mContext = context; mMainExecutor = shellExecutor; mMainHandler = mainHandler; @@ -436,6 +445,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, mDesktopModeEventLogger = desktopModeEventLogger; mDesktopModeUiEventLogger = desktopModeUiEventLogger; mTaskResourceLoader = taskResourceLoader; + mRecentsTransitionHandler = recentsTransitionHandler; shellInit.addInitCallback(this::onInit, this); } @@ -450,6 +460,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, new DesktopModeOnTaskResizeAnimationListener()); mDesktopTasksController.setOnTaskRepositionAnimationListener( new DesktopModeOnTaskRepositionAnimationListener()); + if (Flags.enableDesktopRecentsTransitionsCornersBugfix()) { + mRecentsTransitionHandler.addTransitionStateListener( + new DesktopModeRecentsTransitionStateListener()); + } mDisplayController.addDisplayChangingController(mOnDisplayChangingListener); try { mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener, @@ -1859,6 +1873,38 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, } } + private class DesktopModeRecentsTransitionStateListener + implements RecentsTransitionStateListener { + final Set<Integer> mAnimatingTaskIds = new HashSet<>(); + + @Override + public void onTransitionStateChanged(int state) { + switch (state) { + case RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED: + for (int n = 0; n < mWindowDecorByTaskId.size(); n++) { + int taskId = mWindowDecorByTaskId.keyAt(n); + mAnimatingTaskIds.add(taskId); + setIsRecentsTransitionRunningForTask(taskId, true); + } + return; + case RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING: + // No Recents transition running - clean up window decorations + for (int taskId : mAnimatingTaskIds) { + setIsRecentsTransitionRunningForTask(taskId, false); + } + mAnimatingTaskIds.clear(); + return; + default: + } + } + + private void setIsRecentsTransitionRunningForTask(int taskId, boolean isRecentsRunning) { + final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId); + if (decoration == null) return; + decoration.setIsRecentsTransitionRunning(isRecentsRunning); + } + } + private class DragEventListenerImpl implements DragPositioningCallbackUtility.DragEventListener { @Override @@ -1881,14 +1927,21 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel, // instances, then refer to the list's size and reuse the list for Manage Windows menu. final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService(); try { + // TODO(b/389184897): Move the following into a helper method of + // RecentsTasksController, similar to #findTaskInBackground. + final String packageName = ComponentUtils.getPackageName(info); return activityTaskManager.getRecentTasks(Integer.MAX_VALUE, ActivityManager.RECENT_WITH_EXCLUDED, info.userId).getList().stream().filter( - recentTaskInfo -> (recentTaskInfo.taskId != info.taskId - && recentTaskInfo.baseActivity != null - && recentTaskInfo.baseActivity.getPackageName() - .equals(info.baseActivity.getPackageName()) - ) + recentTaskInfo -> { + if (recentTaskInfo.taskId == info.taskId) { + return false; + } + final String recentTaskPackageName = + ComponentUtils.getPackageName(recentTaskInfo); + return packageName != null + && packageName.equals(recentTaskPackageName); + } ).toList().size(); } catch (RemoteException e) { throw new RuntimeException(e); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 4ac89546c9c7..39a989ce7c7f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -204,6 +204,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin private final MultiInstanceHelper mMultiInstanceHelper; private final WindowDecorCaptionHandleRepository mWindowDecorCaptionHandleRepository; private final DesktopUserRepositories mDesktopUserRepositories; + private boolean mIsRecentsTransitionRunning = false; private Runnable mLoadAppInfoRunnable; private Runnable mSetAppInfoRunnable; @@ -498,7 +499,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop, mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive, mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus, - displayExclusionRegion); + displayExclusionRegion, mIsRecentsTransitionRunning); final WindowDecorLinearLayout oldRootView = mResult.mRootView; final SurfaceControl oldDecorationSurface = mDecorationContainerSurface; @@ -869,7 +870,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin boolean inFullImmersiveMode, @NonNull InsetsState displayInsetsState, boolean hasGlobalFocus, - @NonNull Region displayExclusionRegion) { + @NonNull Region displayExclusionRegion, + boolean shouldIgnoreCornerRadius) { final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode()); final boolean isAppHeader = captionLayoutId == R.layout.desktop_mode_app_header; @@ -1006,13 +1008,19 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin relayoutParams.mWindowDecorConfig = windowDecorConfig; if (DesktopModeStatus.useRoundedCorners()) { - relayoutParams.mCornerRadius = taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM - ? loadDimensionPixelSize(context.getResources(), - R.dimen.desktop_windowing_freeform_rounded_corner_radius) - : INVALID_CORNER_RADIUS; + relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS : + getCornerRadius(context, relayoutParams.mLayoutResId); } } + private static int getCornerRadius(@NonNull Context context, int layoutResId) { + if (layoutResId == R.layout.desktop_mode_app_header) { + return loadDimensionPixelSize(context.getResources(), + R.dimen.desktop_windowing_freeform_rounded_corner_radius); + } + return INVALID_CORNER_RADIUS; + } + /** * If task has focused window decor, return the caption id of the fullscreen caption size * resource. Otherwise, return ID_NULL and caption width be set to task width. @@ -1740,6 +1748,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin } /** + * Declares whether a Recents transition is currently active. + * + * <p> When a Recents transition is active we allow that transition to take ownership of the + * corner radius of its task surfaces, so each window decoration should stop updating the corner + * radius of its task surface during that time. + */ + void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) { + mIsRecentsTransitionRunning = isRecentsTransitionRunning; + } + + /** * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button. */ void onMaximizeButtonHoverExit() { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt index 8dc921c986ce..07496eb0e526 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt @@ -31,6 +31,7 @@ import com.android.internal.jank.Cuj import com.android.internal.jank.InteractionJankMonitor import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.common.DisplayController +import com.android.wm.shell.common.MultiDisplayDragMoveBoundsCalculator import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.transition.Transitions import java.util.concurrent.TimeUnit @@ -69,6 +70,7 @@ class MultiDisplayVeiledResizeTaskPositioner( @DragPositioningCallback.CtrlType private var ctrlType = 0 private var isResizingOrAnimatingResize = false @Surface.Rotation private var rotation = 0 + private var startDisplayId = 0 constructor( taskOrganizer: ShellTaskOrganizer, @@ -95,6 +97,7 @@ class MultiDisplayVeiledResizeTaskPositioner( override fun onDragPositioningStart(ctrlType: Int, displayId: Int, x: Float, y: Float): Rect { this.ctrlType = ctrlType + startDisplayId = displayId taskBoundsAtDragStart.set( desktopWindowDecoration.mTaskInfo.configuration.windowConfiguration.bounds ) @@ -160,16 +163,47 @@ class MultiDisplayVeiledResizeTaskPositioner( interactionJankMonitor.begin( createLongTimeoutJankConfigBuilder(Cuj.CUJ_DESKTOP_MODE_DRAG_WINDOW) ) + val t = transactionSupplier.get() - DragPositioningCallbackUtility.setPositionOnDrag( - desktopWindowDecoration, - repositionTaskBounds, - taskBoundsAtDragStart, - repositionStartPoint, - t, - x, - y, - ) + val startDisplayLayout = displayController.getDisplayLayout(startDisplayId) + val currentDisplayLayout = displayController.getDisplayLayout(displayId) + + if (startDisplayLayout == null || currentDisplayLayout == null) { + // Fall back to single-display drag behavior if any display layout is unavailable. + DragPositioningCallbackUtility.setPositionOnDrag( + desktopWindowDecoration, + repositionTaskBounds, + taskBoundsAtDragStart, + repositionStartPoint, + t, + x, + y, + ) + } else { + val boundsDp = + MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( + startDisplayLayout, + repositionStartPoint, + taskBoundsAtDragStart, + currentDisplayLayout, + x, + y, + ) + repositionTaskBounds.set( + MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( + boundsDp, + startDisplayLayout, + ) + ) + + // TODO(b/383069173): Render drag indicator(s) + + t.setPosition( + desktopWindowDecoration.mTaskSurface, + repositionTaskBounds.left.toFloat(), + repositionTaskBounds.top.toFloat(), + ) + } t.setFrameTimeline(Choreographer.getInstance().vsyncId) t.apply() } @@ -200,13 +234,38 @@ class MultiDisplayVeiledResizeTaskPositioner( } interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_RESIZE_WINDOW) } else { - DragPositioningCallbackUtility.updateTaskBounds( - repositionTaskBounds, - taskBoundsAtDragStart, - repositionStartPoint, - x, - y, - ) + val startDisplayLayout = displayController.getDisplayLayout(startDisplayId) + val currentDisplayLayout = displayController.getDisplayLayout(displayId) + + if (startDisplayLayout == null || currentDisplayLayout == null) { + // Fall back to single-display drag behavior if any display layout is unavailable. + DragPositioningCallbackUtility.updateTaskBounds( + repositionTaskBounds, + taskBoundsAtDragStart, + repositionStartPoint, + x, + y, + ) + } else { + val boundsDp = + MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( + startDisplayLayout, + repositionStartPoint, + taskBoundsAtDragStart, + currentDisplayLayout, + x, + y, + ) + repositionTaskBounds.set( + MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( + boundsDp, + currentDisplayLayout, + ) + ) + + // TODO(b/383069173): Clear drag indicator(s) + } + interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_DRAG_WINDOW) } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 5d1bedb85b5e..fa7183ad0fd8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -967,4 +967,4 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> return Objects.hash(mToken, mOwner, mFrame, Arrays.hashCode(mBoundingRects), mFlags); } } -}
\ No newline at end of file +} diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationLandscape.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationLandscape.kt new file mode 100644 index 000000000000..0feb13d9dded --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationLandscape.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.wm.shell.flicker + +import android.tools.Rotation +import android.tools.flicker.FlickerConfig +import android.tools.flicker.annotation.ExpectedScenarios +import android.tools.flicker.annotation.FlickerConfigProvider +import android.tools.flicker.config.FlickerConfig +import android.tools.flicker.config.FlickerServiceConfig +import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP +import com.android.wm.shell.scenarios.CloseAllAppsWithBackNavigation +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(FlickerServiceJUnit4ClassRunner::class) +class CloseAllAppsWithBackNavigationLandscape : CloseAllAppsWithBackNavigation( + Rotation.ROTATION_90 +) { + // TODO(b/390043833): Add verifications that TO_BACK transition is captured when the back + // navigation button is pressed. + @ExpectedScenarios(["CLOSE_APP", "CLOSE_LAST_APP"]) + @Test + override fun closeAllAppsInDesktop() = super.closeAllAppsInDesktop() + + companion object { + @JvmStatic + @FlickerConfigProvider + fun flickerConfigProvider(): FlickerConfig = + FlickerConfig() + .use(FlickerServiceConfig.DEFAULT) + .use(CLOSE_APP) + .use(CLOSE_LAST_APP) + } +} diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationPortrait.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationPortrait.kt new file mode 100644 index 000000000000..3b77ea5e5264 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/CloseAllAppsWithBackNavigationPortrait.kt @@ -0,0 +1,48 @@ +/* + * 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.wm.shell.flicker + +import android.tools.flicker.FlickerConfig +import android.tools.flicker.annotation.ExpectedScenarios +import android.tools.flicker.annotation.FlickerConfigProvider +import android.tools.flicker.config.FlickerConfig +import android.tools.flicker.config.FlickerServiceConfig +import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_APP +import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.CLOSE_LAST_APP +import com.android.wm.shell.scenarios.CloseAllAppsWithBackNavigation +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(FlickerServiceJUnit4ClassRunner::class) +class CloseAllAppsWithBackNavigationPortrait : CloseAllAppsWithBackNavigation() { + // TODO(b/390043833): Add verifications that TO_BACK transition is captured when the back + // navigation button is pressed. + @ExpectedScenarios(["CLOSE_APP", "CLOSE_LAST_APP"]) + @Test + override fun closeAllAppsInDesktop() = super.closeAllAppsInDesktop() + + companion object { + @JvmStatic + @FlickerConfigProvider + fun flickerConfigProvider(): FlickerConfig = + FlickerConfig() + .use(FlickerServiceConfig.DEFAULT) + .use(CLOSE_APP) + .use(CLOSE_LAST_APP) + } +} diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithBackNavigation.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithBackNavigation.kt new file mode 100644 index 000000000000..319df49cdc03 --- /dev/null +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/CloseAllAppsWithBackNavigation.kt @@ -0,0 +1,73 @@ +/* + * 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.wm.shell.scenarios + +import android.app.Instrumentation +import android.tools.NavBar +import android.tools.Rotation +import android.tools.traces.parsers.WindowManagerStateHelper +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.server.wm.flicker.helpers.DesktopModeAppHelper +import com.android.server.wm.flicker.helpers.MailAppHelper +import com.android.server.wm.flicker.helpers.NonResizeableAppHelper +import com.android.server.wm.flicker.helpers.SimpleAppHelper +import com.android.window.flags.Flags +import com.android.wm.shell.Utils +import org.junit.After +import org.junit.Assume +import org.junit.Before +import org.junit.Ignore +import org.junit.Rule +import org.junit.Test + +@Ignore("Base Test Class") +abstract class CloseAllAppsWithBackNavigation(val rotation: Rotation = Rotation.ROTATION_0) { + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() + private val tapl = LauncherInstrumentation() + private val wmHelper = WindowManagerStateHelper(instrumentation) + private val device = UiDevice.getInstance(instrumentation) + private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation)) + private val mailApp = DesktopModeAppHelper(MailAppHelper(instrumentation)) + private val nonResizeableApp = DesktopModeAppHelper(NonResizeableAppHelper(instrumentation)) + + @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation) + + @Before + fun setup() { + Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet) + Assume.assumeTrue(Flags.enableDesktopWindowingBackNavigation()) + tapl.setEnableRotation(true) + tapl.setExpectedRotation(rotation.value) + testApp.enterDesktopMode(wmHelper, device) + mailApp.launchViaIntent(wmHelper) + nonResizeableApp.launchViaIntent(wmHelper) + } + + @Test + open fun closeAllAppsInDesktop() { + nonResizeableApp.closeDesktopApp(wmHelper, device, usingBackNavigation = true) + mailApp.closeDesktopApp(wmHelper, device, usingBackNavigation = true) + testApp.closeDesktopApp(wmHelper, device, usingBackNavigation = true) + } + + @After + fun teardown() { + testApp.exit(wmHelper) + } +} diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenUnlimitedApps.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenUnlimitedApps.kt index 367c4a437018..16a01d570575 100644 --- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenUnlimitedApps.kt +++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/OpenUnlimitedApps.kt @@ -17,6 +17,8 @@ package com.android.wm.shell.scenarios import android.app.Instrumentation +import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.tools.traces.parsers.WindowManagerStateHelper import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice @@ -43,7 +45,7 @@ abstract class OpenUnlimitedApps() private val device = UiDevice.getInstance(instrumentation) private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation)) - private val mailApp = DesktopModeAppHelper(MailAppHelper(instrumentation)) + private val mailApp = MailAppHelper(instrumentation) private val maxNum = DesktopModeStatus.getMaxTaskLimit(instrumentation.context) @@ -61,7 +63,12 @@ abstract class OpenUnlimitedApps() // Launch new [openTaskNum] tasks. for (i in 1..openTaskNum) { - mailApp.launchViaIntent(wmHelper) + mailApp.launchViaIntent( + wmHelper, + mailApp.openAppIntent.apply { + addFlags(FLAG_ACTIVITY_MULTIPLE_TASK or FLAG_ACTIVITY_NEW_TASK) + } + ) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculatorTest.kt new file mode 100644 index 000000000000..bd924c2b47c1 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayDragMoveBoundsCalculatorTest.kt @@ -0,0 +1,97 @@ +/* + * 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.wm.shell.common + +import android.content.res.Configuration +import android.graphics.PointF +import android.graphics.Rect +import android.graphics.RectF +import android.testing.TestableResources +import com.android.wm.shell.ShellTestCase +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +/** + * Tests for [MultiDisplayDragMoveBoundsCalculator]. + * + * Build/Install/Run: atest WMShellUnitTests:MultiDisplayDragMoveBoundsCalculatorTest + */ +class MultiDisplayDragMoveBoundsCalculatorTest : ShellTestCase() { + private lateinit var resources: TestableResources + + @Before + fun setUp() { + resources = mContext.getOrCreateTestableResources() + val configuration = Configuration() + configuration.uiMode = 0 + resources.overrideConfiguration(configuration) + } + + @Test + fun testCalculateGlobalDpBoundsForDrag() { + val repositionStartPoint = PointF(20f, 40f) + val boundsAtDragStart = Rect(10, 20, 110, 120) + val x = 300f + val y = 400f + val displayLayout0 = + MultiDisplayTestUtil.createSpyDisplayLayout( + MultiDisplayTestUtil.DISPLAY_GLOBAL_BOUNDS_0, + MultiDisplayTestUtil.DISPLAY_DPI_0, + resources.resources, + ) + val displayLayout1 = + MultiDisplayTestUtil.createSpyDisplayLayout( + MultiDisplayTestUtil.DISPLAY_GLOBAL_BOUNDS_1, + MultiDisplayTestUtil.DISPLAY_DPI_1, + resources.resources, + ) + + val actualBoundsDp = + MultiDisplayDragMoveBoundsCalculator.calculateGlobalDpBoundsForDrag( + displayLayout0, + repositionStartPoint, + boundsAtDragStart, + displayLayout1, + x, + y, + ) + + val expectedBoundsDp = RectF(240f, -820f, 340f, -720f) + assertEquals(expectedBoundsDp, actualBoundsDp) + } + + @Test + fun testConvertGlobalDpToLocalPxForRect() { + val displayLayout = + MultiDisplayTestUtil.createSpyDisplayLayout( + MultiDisplayTestUtil.DISPLAY_GLOBAL_BOUNDS_1, + MultiDisplayTestUtil.DISPLAY_DPI_1, + resources.resources, + ) + val rectDp = RectF(150f, -350f, 300f, -250f) + + val actualBoundsPx = + MultiDisplayDragMoveBoundsCalculator.convertGlobalDpToLocalPxForRect( + rectDp, + displayLayout, + ) + + val expectedBoundsPx = Rect(100, 1300, 400, 1500) + assertEquals(expectedBoundsPx, actualBoundsPx) + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayTestUtil.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayTestUtil.kt new file mode 100644 index 000000000000..c8bebf11a82c --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/MultiDisplayTestUtil.kt @@ -0,0 +1,45 @@ +/* + * 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.wm.shell.common + +import android.content.res.Resources +import android.graphics.RectF +import android.util.DisplayMetrics +import android.view.DisplayInfo +import org.mockito.Mockito.spy + +/** Utility class for tests of [DesktopModeWindowDecorViewModel] */ +object MultiDisplayTestUtil { + // We have two displays, display#1 is placed on middle top of display#0: + // +---+ + // | 1 | + // +-+---+-+ + // | 0 | + // +-------+ + val DISPLAY_GLOBAL_BOUNDS_0 = RectF(0f, 0f, 1200f, 800f) + val DISPLAY_GLOBAL_BOUNDS_1 = RectF(100f, -1000f, 1100f, 0f) + val DISPLAY_DPI_0 = DisplayMetrics.DENSITY_DEFAULT + val DISPLAY_DPI_1 = DisplayMetrics.DENSITY_DEFAULT * 2 + + fun createSpyDisplayLayout(globalBounds: RectF, dpi: Int, resources: Resources): DisplayLayout { + val displayInfo = DisplayInfo() + displayInfo.logicalDensityDpi = dpi + val displayLayout = spy(DisplayLayout(displayInfo, resources, true, true)) + displayLayout.setGlobalBoundsDp(globalBounds) + return displayLayout + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index f549b0563827..d13ff79b9518 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -257,6 +257,7 @@ class DesktopTasksControllerTest : ShellTestCase() { // Mock running tasks are registered here so we can get the list from mock shell task organizer private val runningTasks = mutableListOf<RunningTaskInfo>() + private val SECONDARY_DISPLAY_ID = 1 private val DISPLAY_DIMENSION_SHORT = 1600 private val DISPLAY_DIMENSION_LONG = 2560 private val DEFAULT_LANDSCAPE_BOUNDS = Rect(320, 75, 2240, 1275) @@ -316,6 +317,8 @@ class DesktopTasksControllerTest : ShellTestCase() { val tda = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) tda.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)).thenReturn(tda) + whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECONDARY_DISPLAY_ID)) + .thenReturn(tda) whenever( mMockDesktopImmersiveController.exitImmersiveIfApplicable( any(), @@ -1143,6 +1146,21 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test + fun launchIntent_taskInDesktopMode_transitionStarted() { + setUpLandscapeDisplay() + val freeformTask = setUpFreeformTask() + + controller.startLaunchIntentTransition( + freeformTask.baseIntent, + Bundle.EMPTY, + DEFAULT_DISPLAY, + ) + + val wct = getLatestDesktopMixedTaskWct(type = TRANSIT_OPEN) + assertThat(wct.hierarchyOps).hasSize(1) + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_WINDOWING_DYNAMIC_INITIAL_BOUNDS) fun addMoveToDesktopChanges_landscapeDevice_userFullscreenOverride_defaultPortraitBounds() { setUpLandscapeDisplay() @@ -1800,8 +1818,35 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test + @EnableFlags( + FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY, + Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER, + ) + fun moveToNextDisplay_wallpaperOnSystemUser_reorderWallpaperToBack() { + // Set up two display ids + whenever(rootTaskDisplayAreaOrganizer.displayIds) + .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) + // Create a mock for the target display area: second display + val secondDisplayArea = DisplayAreaInfo(MockToken().token(), SECOND_DISPLAY, 0) + whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(SECOND_DISPLAY)) + .thenReturn(secondDisplayArea) + // Add a task and a wallpaper + val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY) + + controller.moveToNextDisplay(task.taskId) + + with(getLatestWct(type = TRANSIT_CHANGE)) { + val wallpaperChange = + hierarchyOps.find { op -> op.container == wallpaperToken.asBinder() } + assertNotNull(wallpaperChange) + assertThat(wallpaperChange.type).isEqualTo(HIERARCHY_OP_TYPE_REORDER) + } + } + + @Test @EnableFlags(FLAG_ENABLE_PER_DISPLAY_DESKTOP_WALLPAPER_ACTIVITY) - fun moveToNextDisplay_removeWallpaper() { + @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER) + fun moveToNextDisplay_wallpaperNotOnSystemUser_removeWallpaper() { // Set up two display ids whenever(rootTaskDisplayAreaOrganizer.displayIds) .thenReturn(intArrayOf(DEFAULT_DISPLAY, SECOND_DISPLAY)) @@ -3561,6 +3606,45 @@ class DesktopTasksControllerTest : ShellTestCase() { } @Test + @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG) + fun onDesktopDragEnd_noIndicatorAndMoveToNewDisplay_reparent() { + val task = setUpFreeformTask() + val spyController = spy(controller) + val mockSurface = mock(SurfaceControl::class.java) + val mockDisplayLayout = mock(DisplayLayout::class.java) + whenever(displayController.getDisplayLayout(task.displayId)).thenReturn(mockDisplayLayout) + whenever(mockDisplayLayout.stableInsets()).thenReturn(Rect(0, 100, 2000, 2000)) + spyController.onDragPositioningMove(task, mockSurface, 200f, Rect(100, 200, 500, 1000)) + + val currentDragBounds = Rect(100, 200, 500, 1000) + whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator) + whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull())) + .thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR) + whenever(motionEvent.displayId).thenReturn(SECONDARY_DISPLAY_ID) + + spyController.onDragPositioningEnd( + task, + mockSurface, + position = Point(100, 200), + inputCoordinate = PointF(200f, 300f), + currentDragBounds, + validDragArea = Rect(0, 50, 2000, 2000), + dragStartBounds = Rect(), + motionEvent, + desktopWindowDecoration, + ) + + verify(transitions) + .startTransition( + eq(TRANSIT_CHANGE), + Mockito.argThat { wct -> + return@argThat wct.hierarchyOps[0].isReparent + }, + eq(null), + ) + } + + @Test fun onDesktopDragEnd_fullscreenIndicator_dragToExitDesktop() { val task = setUpFreeformTask(bounds = Rect(0, 0, 100, 100)) val spyController = spy(controller) @@ -5135,7 +5219,7 @@ class DesktopTasksControllerTest : ShellTestCase() { val arg: ArgumentCaptor<WindowContainerTransaction> = ArgumentCaptor.forClass(WindowContainerTransaction::class.java) verify(desktopMixedTransitionHandler) - .startLaunchTransition(eq(type), capture(arg), anyInt(), anyOrNull(), anyOrNull()) + .startLaunchTransition(eq(type), capture(arg), anyOrNull(), anyOrNull(), anyOrNull()) return arg.value } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java index 7e5d6ce38c5a..28f4ea0c7ada 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java @@ -22,13 +22,13 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; -import static com.android.launcher3.Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK; import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE; import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FREEFORM; import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_FULLSCREEN; import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT; import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -65,8 +65,8 @@ import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.view.SurfaceControl; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.dx.mockito.inline.extended.StaticMockitoSession; @@ -253,7 +253,6 @@ public class RecentTasksControllerTest extends ShellTestCase { t3.taskId, -1); } - @EnableFlags(FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) @Test public void testGetRecentTasks_removesDesktopWallpaperActivity() { RecentTaskInfo t1 = makeTaskInfo(1); @@ -753,15 +752,9 @@ public class RecentTasksControllerTest extends ShellTestCase { /** * Helper to set the raw task list on the controller. */ - private ArrayList<RecentTaskInfo> setRawList( - RecentTaskInfo... tasks) { - ArrayList<RecentTaskInfo> rawList = new ArrayList<>(); - for (RecentTaskInfo task : tasks) { - rawList.add(task); - } - doReturn(rawList).when(mActivityTaskManager).getRecentTasks(anyInt(), anyInt(), + private void setRawList(RecentTaskInfo... tasks) { + doReturn(Arrays.asList(tasks)).when(mActivityTaskManager).getRecentTasks(anyInt(), anyInt(), anyInt()); - return rawList; } /** @@ -794,8 +787,9 @@ public class RecentTasksControllerTest extends ShellTestCase { assertNull(pair.getSplitBounds()); } } - assertTrue("Expected: " + Arrays.toString(expectedTaskIds) + assertArrayEquals("Expected: " + Arrays.toString(expectedTaskIds) + " Received: " + Arrays.toString(flattenedTaskIds), - Arrays.equals(flattenedTaskIds, expectedTaskIds)); + flattenedTaskIds, + expectedTaskIds); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java index 894d238b7e15..ab43119b14c0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentsTransitionHandlerTest.java @@ -169,7 +169,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase { final IResultReceiver finishCallback = mock(IResultReceiver.class); final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner); - verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any()); + verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any(), any()); // Finish and verify no transition remains and that the provided finish callback is called mRecentsTransitionHandler.findController(transition).finish(true /* toHome */, @@ -184,7 +184,7 @@ public class RecentsTransitionHandlerTest extends ShellTestCase { final IRecentsAnimationRunner runner = mock(IRecentsAnimationRunner.class); final IBinder transition = startRecentsTransition(/* synthetic= */ true, runner); - verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any()); + verify(runner).onAnimationStart(any(), any(), any(), any(), any(), any(), any()); mRecentsTransitionHandler.findController(transition).cancel("test"); mMainExecutor.flushAll(); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java index 015ea20767e9..74c2f0e6753a 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/FocusTransitionObserverTest.java @@ -17,7 +17,9 @@ package com.android.wm.shell.transition; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_OPEN; +import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_MOVED_TO_TOP; @@ -127,19 +129,136 @@ public class FocusTransitionObserverTest extends ShellTestCase { true /* isFocusedOnDisplay */, false /* isFocusedGlobally */); } + @Test + public void testTaskFocusSwitch() throws RemoteException { + final SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class); + + // Open 2 tasks on the default display. + TransitionInfo info = mock(TransitionInfo.class); + final List<TransitionInfo.Change> changes = new ArrayList<>(); + setupTaskChange(changes, 1 /* taskId */, TRANSIT_OPEN, + DEFAULT_DISPLAY, true /* focused */); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, never()).onFocusedDisplayChanged(anyInt()); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + changes.clear(); + + setupTaskChange(changes, 2 /* taskId */, TRANSIT_OPEN, + DEFAULT_DISPLAY, true /* focused */); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + false /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(2 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + changes.clear(); + + // Moving a task to front. + changes.clear(); + setupTaskChange(changes, 1 /* taskId */, TRANSIT_TO_FRONT, + DEFAULT_DISPLAY, true /* focused */); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(2 /* taskId */, + false /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + } + + + @Test + public void testTaskMoveToAnotherDisplay() throws RemoteException { + final SurfaceControl.Transaction tx = mock(SurfaceControl.Transaction.class); + + // First, open a task on the default display. + TransitionInfo info = mock(TransitionInfo.class); + final List<TransitionInfo.Change> changes = new ArrayList<>(); + setupTaskChange(changes, 1 /* taskId */, TRANSIT_OPEN, + DEFAULT_DISPLAY, true /* focused */); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, never()).onFocusedDisplayChanged(anyInt()); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + changes.clear(); + + // Open 2 tasks on the secondary display. + setupTaskChange(changes, 2 /* taskId */, TRANSIT_OPEN, + SECONDARY_DISPLAY_ID, true /* focused */); + setupDisplayToTopChange(changes, SECONDARY_DISPLAY_ID); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, times(1)) + .onFocusedDisplayChanged(SECONDARY_DISPLAY_ID); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + true /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(2 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + changes.clear(); + + setupTaskChange(changes, 3 /* taskId */, TRANSIT_OPEN, + SECONDARY_DISPLAY_ID, true /* focused */); + setupDisplayToTopChange(changes, SECONDARY_DISPLAY_ID); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, times(1)).onFocusedTaskChanged(2 /* taskId */, + false /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(3 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + changes.clear(); + + // Move focused task in the secondary display to the default display + setupTaskChange(changes, 3 /* taskId */, TRANSIT_CHANGE, + SECONDARY_DISPLAY_ID, DEFAULT_DISPLAY, true /* focused */); + setupTaskChange(changes, 2 /* taskId */, TRANSIT_TO_FRONT, + SECONDARY_DISPLAY_ID, true /* focused */); + setupDisplayToTopChange(changes, DEFAULT_DISPLAY); + when(info.getChanges()).thenReturn(changes); + mFocusTransitionObserver.updateFocusState(info); + mShellExecutor.flushAll(); + verify(mListener, times(1)).onFocusedTaskChanged(1 /* taskId */, + false /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(2 /* taskId */, + true /* isFocusedOnDisplay */, false /* isFocusedGlobally */); + verify(mListener, times(1)).onFocusedTaskChanged(3 /* taskId */, + true /* isFocusedOnDisplay */, true /* isFocusedGlobally */); + clearInvocations(mListener); + } + private void setupTaskChange(List<TransitionInfo.Change> changes, int taskId, @TransitionMode int mode, int displayId, boolean focused) { + setupTaskChange(changes, taskId, mode, displayId, displayId, focused); + } + + private void setupTaskChange(List<TransitionInfo.Change> changes, int taskId, + @TransitionMode int mode, int startDisplayId, int endDisplayId, boolean focused) { TransitionInfo.Change change = mock(TransitionInfo.Change.class); RunningTaskInfo taskInfo = mock(RunningTaskInfo.class); taskInfo.taskId = taskId; taskInfo.isFocused = focused; when(change.hasFlags(FLAG_MOVED_TO_TOP)).thenReturn(focused); - taskInfo.displayId = displayId; + taskInfo.displayId = endDisplayId; + when(change.getStartDisplayId()).thenReturn(startDisplayId); + when(change.getEndDisplayId()).thenReturn(endDisplayId); when(change.getTaskInfo()).thenReturn(taskInfo); when(change.getMode()).thenReturn(mode); changes.add(change); } + private void setupDisplayToTopChange(List<TransitionInfo.Change> changes, int displayId) { TransitionInfo.Change change = mock(TransitionInfo.Change.class); when(change.hasFlags(FLAG_MOVED_TO_TOP)).thenReturn(true); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java index dd645fd968e4..0a19be4eb959 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java @@ -1781,6 +1781,7 @@ public class ShellTransitionTests extends ShellTestCase { taskInfo.configuration.windowConfiguration.setWindowingMode(windowingMode); taskInfo.configuration.windowConfiguration.setActivityType(activityType); taskInfo.token = mock(WindowContainerToken.class); + taskInfo.baseIntent = mock(Intent.class); return taskInfo; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt index ffe8e7135513..79e9b9c8cd77 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt @@ -59,11 +59,12 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.window.flags.Flags import com.android.wm.shell.R -import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction import com.android.wm.shell.desktopmode.DesktopImmersiveController import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition +import com.android.wm.shell.desktopmode.common.ToggleTaskSizeInteraction +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.shared.desktopmode.DesktopModeStatus import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource import com.android.wm.shell.splitscreen.SplitScreenController @@ -539,7 +540,8 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest onLeftSnapClickListenerCaptor.value.invoke() verify(mockDesktopTasksController, never()) - .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT), + .snapToHalfScreen( + eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.LEFT), eq(ResizeTrigger.MAXIMIZE_BUTTON), eq(InputMethod.UNKNOWN_INPUT_METHOD), eq(decor), @@ -616,11 +618,12 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest onRightSnapClickListenerCaptor.value.invoke() verify(mockDesktopTasksController, never()) - .snapToHalfScreen(eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT), + .snapToHalfScreen( + eq(decor.mTaskInfo), any(), eq(currentBounds), eq(SnapPosition.RIGHT), eq(ResizeTrigger.MAXIMIZE_BUTTON), eq(InputMethod.UNKNOWN_INPUT_METHOD), eq(decor), - ) + ) } @Test @@ -1223,6 +1226,49 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest verify(task2, never()).onExclusionRegionChanged(newRegion) } + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_requestedState_setsTransitionRunning() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + + verify(decoration).setIsRecentsTransitionRunning(true) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_nonRunningState_setsTransitionNotRunning() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_NOT_RUNNING) + + verify(decoration).setIsRecentsTransitionRunning(false) + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX) + fun testRecentsTransitionStateListener_requestedAndAnimating_setsTransitionRunningOnce() { + val task = createTask(windowingMode = WINDOWING_MODE_FREEFORM) + val decoration = setUpMockDecorationForTask(task) + onTaskOpening(task, SurfaceControl()) + + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_REQUESTED) + desktopModeRecentsTransitionStateListener.onTransitionStateChanged( + RecentsTransitionStateListener.TRANSITION_STATE_ANIMATING) + + verify(decoration, times(1)).setIsRecentsTransitionRunning(true) + } + private fun createOpenTaskDecoration( @WindowingMode windowingMode: Int, taskSurface: SurfaceControl = SurfaceControl(), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt index b5e8cebc1277..b44af4733fd2 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt @@ -40,6 +40,7 @@ import android.view.SurfaceControl import android.view.WindowInsets.Type.statusBars import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.internal.jank.InteractionJankMonitor +import com.android.window.flags.Flags import com.android.wm.shell.RootTaskDisplayAreaOrganizer import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase @@ -65,6 +66,8 @@ import com.android.wm.shell.desktopmode.WindowDecorCaptionHandleRepository import com.android.wm.shell.desktopmode.education.AppHandleEducationController import com.android.wm.shell.desktopmode.education.AppToWebEducationController import com.android.wm.shell.freeform.FreeformTaskTransitionStarter +import com.android.wm.shell.recents.RecentsTransitionHandler +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.splitscreen.SplitScreenController import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController @@ -151,6 +154,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { protected val mockFocusTransitionObserver = mock<FocusTransitionObserver>() protected val mockCaptionHandleRepository = mock<WindowDecorCaptionHandleRepository>() protected val mockDesktopRepository: DesktopRepository = mock<DesktopRepository>() + protected val mockRecentsTransitionHandler = mock<RecentsTransitionHandler>() protected val motionEvent = mock<MotionEvent>() val displayLayout = mock<DisplayLayout>() protected lateinit var spyContext: TestableContext @@ -164,6 +168,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { protected lateinit var mockitoSession: StaticMockitoSession protected lateinit var shellInit: ShellInit internal lateinit var desktopModeOnInsetsChangedListener: DesktopModeOnInsetsChangedListener + protected lateinit var desktopModeRecentsTransitionStateListener: RecentsTransitionStateListener protected lateinit var displayChangingListener: DisplayChangeController.OnDisplayChangingListener internal lateinit var desktopModeOnKeyguardChangedListener: DesktopModeKeyguardChangeListener @@ -177,6 +182,7 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { spyContext.addMockSystemService(InputManager::class.java, mockInputManager) desktopModeEventLogger = mock<DesktopModeEventLogger>() whenever(mockDesktopUserRepositories.current).thenReturn(mockDesktopRepository) + whenever(mockDisplayController.getDisplayContext(any())).thenReturn(spyContext) whenever(mockDesktopUserRepositories.getProfile(anyInt())) .thenReturn(mockDesktopRepository) desktopModeWindowDecorViewModel = DesktopModeWindowDecorViewModel( @@ -219,7 +225,8 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { mockFocusTransitionObserver, desktopModeEventLogger, mock<DesktopModeUiEventLogger>(), - mock<WindowDecorTaskResourceLoader>() + mock<WindowDecorTaskResourceLoader>(), + mockRecentsTransitionHandler, ) desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController) whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout) @@ -256,6 +263,13 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() { verify(displayInsetsController) .addGlobalInsetsChangedListener(insetsChangedCaptor.capture()) desktopModeOnInsetsChangedListener = insetsChangedCaptor.firstValue + val recentsTransitionStateListenerCaptor = argumentCaptor<RecentsTransitionStateListener>() + if (Flags.enableDesktopRecentsTransitionsCornersBugfix()) { + verify(mockRecentsTransitionHandler) + .addTransitionStateListener(recentsTransitionStateListenerCaptor.capture()) + desktopModeRecentsTransitionStateListener = + recentsTransitionStateListenerCaptor.firstValue + } val keyguardChangedCaptor = argumentCaptor<DesktopModeKeyguardChangeListener>() verify(mockShellController).addKeyguardChangeListener(keyguardChangedCaptor.capture()) diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java index 6b02aeffd42a..9ea5fd6e1abe 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java @@ -169,6 +169,7 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { private static final boolean DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED = false; private static final boolean DEFAULT_IS_IN_FULL_IMMERSIVE_MODE = false; private static final boolean DEFAULT_HAS_GLOBAL_FOCUS = true; + private static final boolean DEFAULT_SHOULD_IGNORE_CORNER_RADIUS = false; @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT); @@ -396,6 +397,31 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { } @Test + public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() { + final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true); + taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM); + fillRoundedCornersResources(/* fillValue= */ 30); + RelayoutParams relayoutParams = new RelayoutParams(); + + DesktopModeWindowDecoration.updateRelayoutParams( + relayoutParams, + mTestableContext, + taskInfo, + mMockSplitScreenController, + DEFAULT_APPLY_START_TRANSACTION_ON_DRAW, + DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP, + DEFAULT_IS_STATUSBAR_VISIBLE, + DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED, + DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, + new InsetsState(), + DEFAULT_HAS_GLOBAL_FOCUS, + mExclusionRegion, + /* shouldIgnoreCornerRadius= */ true); + + assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS); + } + + @Test @EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY) public void updateRelayoutParams_appHeader_usesTaskDensity() { final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources() @@ -634,7 +660,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, insetsState, DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); // Takes status bar inset as padding, ignores caption bar inset. assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50); @@ -659,7 +686,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsInsetSource).isFalse(); } @@ -683,7 +711,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); // Header is always shown because it's assumed the status bar is always visible. assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -707,7 +736,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); } @@ -730,7 +760,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -753,7 +784,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -777,7 +809,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isTrue(); @@ -793,7 +826,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -817,7 +851,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { /* inFullImmersiveMode */ true, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); assertThat(relayoutParams.mIsCaptionVisible).isFalse(); } @@ -1480,7 +1515,8 @@ public class DesktopModeWindowDecorationTests extends ShellTestCase { DEFAULT_IS_IN_FULL_IMMERSIVE_MODE, new InsetsState(), DEFAULT_HAS_GLOBAL_FOCUS, - mExclusionRegion); + mExclusionRegion, + DEFAULT_SHOULD_IGNORE_CORNER_RADIUS); } private DesktopModeWindowDecoration createWindowDecoration( diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt index f179cac32244..2207c705d7dc 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt @@ -17,14 +17,14 @@ package com.android.wm.shell.windowdecor import android.app.ActivityManager import android.app.WindowConfiguration -import android.content.Context -import android.content.res.Resources +import android.content.res.Configuration import android.graphics.Point import android.graphics.Rect import android.os.Handler import android.os.IBinder import android.os.Looper import android.testing.AndroidTestingRunner +import android.testing.TestableResources import android.view.Display import android.view.Surface.ROTATION_0 import android.view.Surface.ROTATION_270 @@ -41,6 +41,7 @@ import com.android.wm.shell.ShellTaskOrganizer import com.android.wm.shell.ShellTestCase import com.android.wm.shell.common.DisplayController import com.android.wm.shell.common.DisplayLayout +import com.android.wm.shell.common.MultiDisplayTestUtil import com.android.wm.shell.transition.Transitions import com.android.wm.shell.transition.Transitions.TransitionFinishCallback import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM @@ -55,6 +56,7 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mockito.any import org.mockito.Mockito.argThat +import org.mockito.Mockito.doAnswer import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.never @@ -82,7 +84,6 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { @Mock private lateinit var taskBinder: IBinder @Mock private lateinit var mockDisplayController: DisplayController - @Mock private lateinit var mockDisplayLayout: DisplayLayout @Mock private lateinit var mockDisplay: Display @Mock private lateinit var mockTransactionFactory: Supplier<SurfaceControl.Transaction> @Mock private lateinit var mockTransaction: SurfaceControl.Transaction @@ -90,9 +91,11 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { @Mock private lateinit var mockTransitionInfo: TransitionInfo @Mock private lateinit var mockFinishCallback: TransitionFinishCallback @Mock private lateinit var mockTransitions: Transitions - @Mock private lateinit var mockContext: Context - @Mock private lateinit var mockResources: Resources @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor + private lateinit var resources: TestableResources + private lateinit var spyDisplayLayout0: DisplayLayout + private lateinit var spyDisplayLayout1: DisplayLayout + private val mainHandler = Handler(Looper.getMainLooper()) private lateinit var taskPositioner: MultiDisplayVeiledResizeTaskPositioner @@ -101,24 +104,45 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) - mockDesktopWindowDecoration.mDisplay = mockDisplay - mockDesktopWindowDecoration.mDecorWindowContext = mockContext - whenever(mockContext.getResources()).thenReturn(mockResources) whenever(taskToken.asBinder()).thenReturn(taskBinder) - whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout) - whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI) - whenever(mockDisplayLayout.getStableBounds(any())).thenAnswer { i -> - if ( - mockDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration - .displayRotation == ROTATION_90 || + mockDesktopWindowDecoration.mDisplay = mockDisplay + mockDesktopWindowDecoration.mDecorWindowContext = mContext + resources = mContext.orCreateTestableResources + val resourceConfiguration = Configuration() + resourceConfiguration.uiMode = 0 + resources.overrideConfiguration(resourceConfiguration) + spyDisplayLayout0 = + MultiDisplayTestUtil.createSpyDisplayLayout( + MultiDisplayTestUtil.DISPLAY_GLOBAL_BOUNDS_0, + MultiDisplayTestUtil.DISPLAY_DPI_0, + resources.resources, + ) + spyDisplayLayout1 = + MultiDisplayTestUtil.createSpyDisplayLayout( + MultiDisplayTestUtil.DISPLAY_GLOBAL_BOUNDS_1, + MultiDisplayTestUtil.DISPLAY_DPI_1, + resources.resources, + ) + whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID_0)).thenReturn(spyDisplayLayout0) + whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID_1)).thenReturn(spyDisplayLayout1) + whenever(spyDisplayLayout0.densityDpi()).thenReturn(DENSITY_DPI) + whenever(spyDisplayLayout1.densityDpi()).thenReturn(DENSITY_DPI) + doAnswer { i -> + val rect = i.getArgument<Rect>(0) + if ( mockDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration - .displayRotation == ROTATION_270 - ) { - (i.arguments.first() as Rect).set(STABLE_BOUNDS_LANDSCAPE) - } else { - (i.arguments.first() as Rect).set(STABLE_BOUNDS_PORTRAIT) + .displayRotation == ROTATION_90 || + mockDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration + .displayRotation == ROTATION_270 + ) { + rect.set(STABLE_BOUNDS_LANDSCAPE) + } else { + rect.set(STABLE_BOUNDS_PORTRAIT) + } + null } - } + .`when`(spyDisplayLayout0) + .getStableBounds(any()) `when`(mockTransactionFactory.get()).thenReturn(mockTransaction) mockDesktopWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply { @@ -127,14 +151,14 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { minWidth = MIN_WIDTH minHeight = MIN_HEIGHT defaultMinSize = DEFAULT_MIN - displayId = DISPLAY_ID + displayId = DISPLAY_ID_0 configuration.windowConfiguration.setBounds(STARTING_BOUNDS) configuration.windowConfiguration.displayRotation = ROTATION_90 isResizeable = true } `when`(mockDesktopWindowDecoration.calculateValidDragArea()).thenReturn(VALID_DRAG_AREA) mockDesktopWindowDecoration.mDisplay = mockDisplay - whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID } + whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID_0 } taskPositioner = MultiDisplayVeiledResizeTaskPositioner( @@ -153,14 +177,14 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { fun testDragResize_noMove_doesNotShowResizeVeil() = runOnUiThread { taskPositioner.onDragPositioningStart( CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) verify(mockDesktopWindowDecoration, never()).showResizeVeil(STARTING_BOUNDS) taskPositioner.onDragPositioningEnd( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) @@ -185,13 +209,13 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { fun testDragResize_movesTask_doesNotShowResizeVeil() = runOnUiThread { taskPositioner.onDragPositioningStart( CTRL_TYPE_UNDEFINED, - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) taskPositioner.onDragPositioningMove( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat() + 60, STARTING_BOUNDS.top.toFloat() + 100, ) @@ -205,7 +229,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { val endBounds = taskPositioner.onDragPositioningEnd( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat() + 70, STARTING_BOUNDS.top.toFloat() + 20, ) @@ -221,16 +245,39 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { } @Test + fun testDragResize_movesTaskToNewDisplay() = runOnUiThread { + taskPositioner.onDragPositioningStart( + CTRL_TYPE_UNDEFINED, + DISPLAY_ID_0, + STARTING_BOUNDS.left.toFloat(), + STARTING_BOUNDS.top.toFloat(), + ) + + taskPositioner.onDragPositioningMove(DISPLAY_ID_1, 200f, 1900f) + + val rectAfterMove = Rect(200, -50, 300, 50) + verify(mockTransaction) + .setPosition(any(), eq(rectAfterMove.left.toFloat()), eq(rectAfterMove.top.toFloat())) + + val endBounds = taskPositioner.onDragPositioningEnd(DISPLAY_ID_1, 300f, 450f) + val rectAfterEnd = Rect(300, 450, 500, 650) + + verify(mockDesktopWindowDecoration, never()).showResizeVeil(any()) + verify(mockDesktopWindowDecoration, never()).hideResizeVeil() + Assert.assertEquals(rectAfterEnd, endBounds) + } + + @Test fun testDragResize_resize_boundsUpdateOnEnd() = runOnUiThread { taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT or CTRL_TYPE_TOP, - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat(), ) taskPositioner.onDragPositioningMove( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.right.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10, ) @@ -252,7 +299,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { ) taskPositioner.onDragPositioningEnd( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.right.toFloat() + 20, STARTING_BOUNDS.top.toFloat() + 20, ) @@ -278,20 +325,20 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { @Test fun testDragResize_noEffectiveMove_skipsTransactionOnEnd() = runOnUiThread { taskPositioner.onDragPositioningStart( - DISPLAY_ID, + DISPLAY_ID_0, CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) taskPositioner.onDragPositioningMove( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) taskPositioner.onDragPositioningEnd( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat() + 10, STARTING_BOUNDS.top.toFloat() + 10, ) @@ -326,16 +373,16 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { fun testDragResize_drag_setBoundsNotRunIfDragEndsInDisallowedEndArea() = runOnUiThread { taskPositioner.onDragPositioningStart( CTRL_TYPE_UNDEFINED, // drag - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) val newX = STARTING_BOUNDS.left.toFloat() + 5 val newY = DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT.toFloat() - 1 - taskPositioner.onDragPositioningMove(DISPLAY_ID, newX, newY) + taskPositioner.onDragPositioningMove(DISPLAY_ID_0, newX, newY) - taskPositioner.onDragPositioningEnd(DISPLAY_ID, newX, newY) + taskPositioner.onDragPositioningEnd(DISPLAY_ID_0, newX, newY) verify(mockShellTaskOrganizer, never()) .applyTransaction( @@ -354,7 +401,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { mockDesktopWindowDecoration.mHasGlobalFocus = false taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT, // Resize right - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) @@ -375,7 +422,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { mockDesktopWindowDecoration.mHasGlobalFocus = true taskPositioner.onDragPositioningStart( CTRL_TYPE_RIGHT, // Resize right - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) @@ -396,7 +443,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { mockDesktopWindowDecoration.mHasGlobalFocus = false taskPositioner.onDragPositioningStart( CTRL_TYPE_UNDEFINED, // drag - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) @@ -427,7 +474,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { rectAfterDrag.right += 2000 rectAfterDrag.bottom = STABLE_BOUNDS_LANDSCAPE.bottom // First drag; we should fetch stable bounds. - verify(mockDisplayLayout, times(1)).getStableBounds(any()) + verify(spyDisplayLayout0, times(1)).getStableBounds(any()) verify(mockTransitions) .startTransition( eq(TRANSIT_CHANGE), @@ -451,7 +498,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { ) // Display did not rotate; we should use previous stable bounds - verify(mockDisplayLayout, times(1)).getStableBounds(any()) + verify(spyDisplayLayout0, times(1)).getStableBounds(any()) // Rotate the screen to portrait mockDesktopWindowDecoration.mTaskInfo.apply { @@ -482,7 +529,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { eq(taskPositioner), ) // Display has rotated; we expect a new stable bounds. - verify(mockDisplayLayout, times(2)).getStableBounds(any()) + verify(spyDisplayLayout0, times(2)).getStableBounds(any()) } @Test @@ -491,13 +538,13 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { taskPositioner.onDragPositioningStart( CTRL_TYPE_TOP or CTRL_TYPE_RIGHT, - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) taskPositioner.onDragPositioningMove( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat() - 20, STARTING_BOUNDS.top.toFloat() - 20, ) @@ -507,7 +554,7 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { verify(mockDragEventListener, times(1)).onDragMove(eq(TASK_ID)) taskPositioner.onDragPositioningEnd( - DISPLAY_ID, + DISPLAY_ID_0, STARTING_BOUNDS.left.toFloat(), STARTING_BOUNDS.top.toFloat(), ) @@ -568,10 +615,10 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { } private fun performDrag(startX: Float, startY: Float, endX: Float, endY: Float, ctrlType: Int) { - taskPositioner.onDragPositioningStart(ctrlType, DISPLAY_ID, startX, startY) - taskPositioner.onDragPositioningMove(DISPLAY_ID, endX, endY) + taskPositioner.onDragPositioningStart(ctrlType, DISPLAY_ID_0, startX, startY) + taskPositioner.onDragPositioningMove(DISPLAY_ID_0, endX, endY) - taskPositioner.onDragPositioningEnd(DISPLAY_ID, endX, endY) + taskPositioner.onDragPositioningEnd(DISPLAY_ID_0, endX, endY) } companion object { @@ -580,7 +627,8 @@ class MultiDisplayVeiledResizeTaskPositionerTest : ShellTestCase() { private const val MIN_HEIGHT = 10 private const val DENSITY_DPI = 20 private const val DEFAULT_MIN = 40 - private const val DISPLAY_ID = 1 + private const val DISPLAY_ID_0 = 0 + private const val DISPLAY_ID_1 = 1 private const val NAVBAR_HEIGHT = 50 private const val CAPTION_HEIGHT = 50 private const val DISALLOWED_AREA_FOR_END_BOUNDS_HEIGHT = 10 diff --git a/libs/androidfw/ApkParsing.cpp b/libs/androidfw/ApkParsing.cpp index 7eedfdb5c921..b80c8755f23e 100644 --- a/libs/androidfw/ApkParsing.cpp +++ b/libs/androidfw/ApkParsing.cpp @@ -33,7 +33,7 @@ const size_t LIB_SUFFIX_LEN = LIB_SUFFIX.size(); static const std::array<std::string_view, 2> abis = {"arm64-v8a", "x86_64"}; namespace android::util { -const char* ValidLibraryPathLastSlash(const char* fileName, bool suppress64Bit, bool debuggable) { +const char* ValidLibraryPathLastSlash(const char* fileName, bool suppress64Bit) { // Make sure the filename is at least to the minimum library name size. const size_t fileNameLen = strlen(fileName); static const size_t minLength = APK_LIB_LEN + 2 + LIB_PREFIX_LEN + 1 + LIB_SUFFIX_LEN; @@ -66,14 +66,6 @@ const char* ValidLibraryPathLastSlash(const char* fileName, bool suppress64Bit, return nullptr; } - if (!debuggable) { - // Make sure the filename starts with lib and ends with ".so". - if (strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX.data(), LIB_SUFFIX_LEN) != 0 - || strncmp(lastSlash, LIB_PREFIX.data(), LIB_PREFIX_LEN) != 0) { - return nullptr; - } - } - // Don't include 64 bit versions if they are suppressed if (suppress64Bit && std::find(abis.begin(), abis.end(), std::string_view( fileName + APK_LIB_LEN, lastSlash - fileName - APK_LIB_LEN)) != abis.end()) { diff --git a/libs/androidfw/include/androidfw/ApkParsing.h b/libs/androidfw/include/androidfw/ApkParsing.h index 194eaae8e12a..b288e152f383 100644 --- a/libs/androidfw/include/androidfw/ApkParsing.h +++ b/libs/androidfw/include/androidfw/ApkParsing.h @@ -24,7 +24,7 @@ extern const size_t APK_LIB_LEN; namespace android::util { // Checks if filename is a valid library path and returns a pointer to the last slash in the path // if it is, nullptr otherwise -const char* ValidLibraryPathLastSlash(const char* filename, bool suppress64Bit, bool debuggable); +const char* ValidLibraryPathLastSlash(const char* filename, bool suppress64Bit); // Equivalent to android.os.FileUtils.isFilenameSafe bool isFilenameSafe(const char* filename); diff --git a/libs/androidfw/tests/ApkParsing_test.cpp b/libs/androidfw/tests/ApkParsing_test.cpp index ac1dc9b88463..f1f9d7166914 100644 --- a/libs/androidfw/tests/ApkParsing_test.cpp +++ b/libs/androidfw/tests/ApkParsing_test.cpp @@ -27,57 +27,45 @@ using ::testing::NotNull; namespace android { TEST(ApkParsingTest, ValidArm64Path) { const char* path = "lib/arm64-v8a/library.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, NotNull()); ASSERT_THAT(lastSlash, Eq(path + 13)); } TEST(ApkParsingTest, ValidArm64PathButSuppressed) { const char* path = "lib/arm64-v8a/library.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, true, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, true); ASSERT_THAT(lastSlash, IsNull()); } TEST(ApkParsingTest, ValidArm32Path) { const char* path = "lib/armeabi-v7a/library.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, NotNull()); ASSERT_THAT(lastSlash, Eq(path + 15)); } -TEST(ApkParsingTest, InvalidMustStartWithLib) { - const char* path = "lib/arm64-v8a/random.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); - ASSERT_THAT(lastSlash, IsNull()); -} - -TEST(ApkParsingTest, InvalidMustEndInSo) { - const char* path = "lib/arm64-v8a/library.txt"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); - ASSERT_THAT(lastSlash, IsNull()); -} - TEST(ApkParsingTest, InvalidCharacter) { const char* path = "lib/arm64-v8a/lib#.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, IsNull()); } TEST(ApkParsingTest, InvalidSubdirectories) { const char* path = "lib/arm64-v8a/anything/library.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, IsNull()); } TEST(ApkParsingTest, InvalidFileAtRoot) { const char* path = "lib/library.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, IsNull()); } TEST(ApkParsingTest, InvalidPrefix) { const char* path = "assets/libhello.so"; - auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + auto lastSlash = util::ValidLibraryPathLastSlash(path, false); ASSERT_THAT(lastSlash, IsNull()); } }
\ No newline at end of file diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index 5e71d3360f39..2851dd8b1003 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -42,6 +42,16 @@ flag { } flag { + name: "high_contrast_text_inner_text_color" + namespace: "accessibility" + description: "Render text color by modifying its brightness instead of defaulting to black and white" + bug: "384793956" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { name: "hdr_10bit_plus" namespace: "core_graphics" description: "Use 10101010 and FP16 formats for HDR-UI when available" diff --git a/libs/hwui/hwui/DrawTextFunctor.h b/libs/hwui/hwui/DrawTextFunctor.h index e05c3d695463..008b693edf02 100644 --- a/libs/hwui/hwui/DrawTextFunctor.h +++ b/libs/hwui/hwui/DrawTextFunctor.h @@ -37,6 +37,9 @@ namespace flags { constexpr bool high_contrast_text_small_text_rect() { return false; } +constexpr bool high_contrast_text_inner_text_color() { + return false; +} } // namespace flags #endif @@ -126,7 +129,25 @@ public: // inner gDrawTextBlobMode = DrawTextBlobMode::HctInner; Paint innerPaint(paint); - simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint); + if (flags::high_contrast_text_inner_text_color()) { + // Preserve some color information while still ensuring sufficient contrast. + // Thus we increase the lightness to make the color stand out against a black + // background, and vice-versa. For grayscale, we retain some gray to indicate + // states like disabled or to distinguish links. + bool isGrayscale = abs(lab.a) < 1 && abs(lab.b) < 1; + if (isGrayscale) { + if (darken) { + lab.L = lab.L < 40 ? 0 : 20; + } else { + lab.L = lab.L > 60 ? 100 : 80; + } + } else { + lab.L = darken ? 20 : 90; + } + simplifyPaint(uirenderer::LabToSRGB(lab, SK_AlphaOPAQUE), &innerPaint); + } else { + simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint); + } innerPaint.setStyle(SkPaint::kFill_Style); canvas->drawGlyphs(glyphFunc, glyphCount, innerPaint, x, y, totalAdvance); gDrawTextBlobMode = DrawTextBlobMode::Normal; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 69fe40c755ea..6ab8e4e0e2ab 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -323,6 +323,7 @@ void RenderThread::initGrContextOptions(GrContextOptions& options) { } void RenderThread::destroyRenderingContext() { + ATRACE_CALL(); mFunctorManager.onContextDestroyed(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { if (mEglManager->hasEglContext()) { @@ -520,7 +521,10 @@ void RenderThread::preload() { // EGL driver is always preloaded only if HWUI renders with GL. if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { if (Properties::earlyPreloadGlContext()) { - queue().post([this]() { requireGlContext(); }); + queue().post([this]() { + ATRACE_NAME("earlyPreloadGlContext"); + requireGlContext(); + }); } else { std::thread eglInitThread([]() { eglGetDisplay(EGL_DEFAULT_DISPLAY); }); eglInitThread.detach(); @@ -528,9 +532,6 @@ void RenderThread::preload() { } else { requireVkContext(); } - if (Properties::earlyPreloadGlContext()) { - queue().post([]() { GraphicBufferAllocator::getInstance(); }); - } HardwareBitmapUploader::initialize(); } diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java index f42017dc835a..3104f9d42891 100644 --- a/media/java/android/media/MediaRoute2ProviderService.java +++ b/media/java/android/media/MediaRoute2ProviderService.java @@ -503,7 +503,10 @@ public abstract class MediaRoute2ProviderService extends Service { String sessionId = sessionInfo.getId(); synchronized (mSessionLock) { - if (mSessionInfos.containsKey(sessionId)) { + var mediaStreams = mOngoingMediaStreams.get(sessionId); + if (Flags.enableMirroringInMediaRouter2() && mediaStreams != null) { + mediaStreams.mSessionInfo = sessionInfo; + } else if (mSessionInfos.containsKey(sessionId)) { mSessionInfos.put(sessionId, sessionInfo); } else { Log.w(TAG, "notifySessionUpdated: Ignoring unknown session info."); @@ -836,6 +839,9 @@ public abstract class MediaRoute2ProviderService extends Service { List<RoutingSessionInfo> sessions; synchronized (mSessionLock) { sessions = new ArrayList<>(mSessionInfos.values()); + if (Flags.enableMirroringInMediaRouter2()) { + mOngoingMediaStreams.values().forEach(it -> sessions.add(it.mSessionInfo)); + } } try { @@ -888,7 +894,13 @@ public abstract class MediaRoute2ProviderService extends Service { Log.w(TAG, description + ": Ignoring empty sessionId from system service."); return false; } - if (getSessionInfo(sessionId) == null) { + boolean idMatchesSystemSession = false; + if (Flags.enableMirroringInMediaRouter2()) { + synchronized (mSessionLock) { + idMatchesSystemSession = mOngoingMediaStreams.containsKey(sessionId); + } + } + if (!idMatchesSystemSession && getSessionInfo(sessionId) == null) { Log.w(TAG, description + ": Ignoring unknown session from system service. " + "sessionId=" + sessionId); return false; @@ -1079,8 +1091,8 @@ public abstract class MediaRoute2ProviderService extends Service { * * @hide */ - @GuardedBy("MediaRoute2ProviderService.this.mSessionLock") @NonNull + // Access guarded by mSessionsLock, but it's not convenient to enforce through @GuardedBy. private RoutingSessionInfo mSessionInfo; // TODO: b/380431086: Add the video equivalent. diff --git a/media/java/android/media/quality/MediaQualityManager.java b/media/java/android/media/quality/MediaQualityManager.java index aeb028ccd0a6..b7269256a449 100644 --- a/media/java/android/media/quality/MediaQualityManager.java +++ b/media/java/android/media/quality/MediaQualityManager.java @@ -18,6 +18,7 @@ package android.media.quality; import android.annotation.CallbackExecutor; import android.annotation.FlaggedApi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; @@ -35,6 +36,8 @@ import androidx.annotation.RequiresPermission; import com.android.internal.util.Preconditions; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -74,6 +77,39 @@ public final class MediaQualityManager { */ public static final String OPTION_INCLUDE_PARAMETERS = "include_parameters"; + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({AMBIENT_BACKLIGHT_EVENT_ENABLED, AMBIENT_BACKLIGHT_EVENT_DISABLED, + AMBIENT_BACKLIGHT_EVENT_METADATA, + AMBIENT_BACKLIGHT_EVENT_INTERRUPTED}) + public @interface AmbientBacklightEventTypes {} + + /** + * Event type for ambient backlight events. The ambient backlight is enabled. + * @hide + */ + public static final int AMBIENT_BACKLIGHT_EVENT_ENABLED = 1; + + /** + * Event type for ambient backlight events. The ambient backlight is disabled. + * @hide + */ + public static final int AMBIENT_BACKLIGHT_EVENT_DISABLED = 2; + + /** + * Event type for ambient backlight events. The ambient backlight metadata is + * available. + * @hide + */ + public static final int AMBIENT_BACKLIGHT_EVENT_METADATA = 3; + + /** + * Event type for ambient backlight events. The ambient backlight event is + * preempted by another application. + * @hide + */ + public static final int AMBIENT_BACKLIGHT_EVENT_INTERRUPTED = 4; + /** * @hide diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig index 3451dfc559ee..28da55656177 100644 --- a/media/java/android/media/tv/flags/media_tv.aconfig +++ b/media/java/android/media/tv/flags/media_tv.aconfig @@ -120,3 +120,13 @@ flag { description: "Collect physical address from HDMI-CEC messages in metrics" bug: "376001043" } + +flag { + name: "tif_extension_standardization_bugfix" + namespace: "tv_os" + description: "Bug fix flag for standardizing AIDL extension interface of TIS" + bug: "389779152" + metadata { + purpose: PURPOSE_BUGFIX + } +}
\ No newline at end of file diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 2fe069af638a..bf330dab266c 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -701,6 +701,9 @@ void FilterClientCallbackImpl::getMediaEvent(const jobjectArray& arr, const int // Protect mFilterClient from being set to null. android::Mutex::Autolock autoLock(mLock); + if (mFilterClient == nullptr) { + return; + } uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size; if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 || (dataLength > 0 && (dataLength + offset) < avSharedMemSize)) { @@ -868,10 +871,18 @@ void FilterClientCallbackImpl::getRestartEvent(const jobjectArray& arr, const in void FilterClientCallbackImpl::onFilterEvent(const vector<DemuxFilterEvent> &events) { ALOGV("FilterClientCallbackImpl::onFilterEvent"); JNIEnv *env = AndroidRuntime::getJNIEnv(); + ScopedLocalRef<jobjectArray> array(env); if (!events.empty()) { array.reset(env->NewObjectArray(events.size(), mEventClass, nullptr)); + if (env->IsSameObject(array.get(), nullptr)) { + // It can happen when FilterClientCallbackImpl release the resource + // in another thread. + ALOGE("FilterClientCallbackImpl::onFilterEvent:" + "Unable to create object array of filter events. Ignoring callback."); + return; + } } for (int i = 0, arraySize = 0; i < events.size(); i++) { @@ -1070,14 +1081,15 @@ FilterClientCallbackImpl::FilterClientCallbackImpl() { FilterClientCallbackImpl::~FilterClientCallbackImpl() { JNIEnv *env = AndroidRuntime::getJNIEnv(); - { - android::Mutex::Autolock autoLock(mLock); - if (mFilterObj != nullptr) { - env->DeleteWeakGlobalRef(mFilterObj); - mFilterObj = nullptr; - } - mFilterClient = nullptr; + + android::Mutex::Autolock autoLock(mLock); + + if (mFilterObj != nullptr) { + env->DeleteWeakGlobalRef(mFilterObj); + mFilterObj = nullptr; } + mFilterClient = nullptr; + env->DeleteGlobalRef(mEventClass); env->DeleteGlobalRef(mSectionEventClass); env->DeleteGlobalRef(mMediaEventClass); diff --git a/native/android/TEST_MAPPING b/native/android/TEST_MAPPING index 70560a84b88e..456c719effc0 100644 --- a/native/android/TEST_MAPPING +++ b/native/android/TEST_MAPPING @@ -25,5 +25,19 @@ "name": "NativeThermalUnitTestCases", "file_patterns": ["thermal.cpp"] } + ], + "postsubmit": [ + { + "file_patterns": ["system_health.cpp"], + "name": "NativeSystemHealthUnitTestCases" + }, + { + "file_patterns": ["system_health.cpp"], + "name": "CtsSystemHealthTestCases", + "options": [ + {"exclude-annotation": "androidx.test.filters.FlakyTest"}, + {"exclude-annotation": "org.junit.Ignore"} + ] + } ] } diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp index 4180710534c3..bc273c2d0833 100644 --- a/native/graphics/jni/Android.bp +++ b/native/graphics/jni/Android.bp @@ -102,8 +102,13 @@ cc_defaults { static_libs: ["libarect"], fuzz_config: { cc: [ + // Alphabetical order -- assign to skia-android-triage@google.com + "danieldilan@google.com", "dichenzhang@google.com", - "scroggo@google.com", + "fmalita@google.com", + "jreck@google.com", + "nscobie@google.com", + "skia-android-triage@google.com", ], asan_options: [ "detect_odr_violation=1", diff --git a/packages/CarrierDefaultApp/res/values-iw/strings.xml b/packages/CarrierDefaultApp/res/values-iw/strings.xml index 9e5a8b55bae6..9db81e0dded5 100644 --- a/packages/CarrierDefaultApp/res/values-iw/strings.xml +++ b/packages/CarrierDefaultApp/res/values-iw/strings.xml @@ -5,7 +5,7 @@ <string name="android_system_label" msgid="2797790869522345065">"ספק שירות לנייד"</string> <string name="portal_notification_id" msgid="5155057562457079297">"ניצלת את מכסת הנתונים הסלולריים"</string> <string name="no_data_notification_id" msgid="668400731803969521">"חבילת הגלישה שלך הושבתה"</string> - <string name="portal_notification_detail" msgid="2295729385924660881">"הקש כדי לעבור לאתר של %s"</string> + <string name="portal_notification_detail" msgid="2295729385924660881">"יש ללחוץ כדי לעבור לאתר של %s"</string> <string name="no_data_notification_detail" msgid="3112125343857014825">"פנה לספק השירות %s"</string> <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"אין חיבור לחבילת גלישה"</string> <string name="no_mobile_data_connection" msgid="544980465184147010">"אפשר להוסיף חבילת גלישה או חבילת נדידה באמצעות %s"</string> diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml index ba02bf696407..9476dc55e86a 100644 --- a/packages/CompanionDeviceManager/res/values-af/strings.xml +++ b/packages/CompanionDeviceManager/res/values-af/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Metgeseltoestel-bestuurder"</string> <string name="confirmation_title" msgid="2244241995958340998">"Gee die app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Maak seker dat hierdie <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> se <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> aangeskakel is en hou jou <xliff:g id="PROFILE_NAME">%3$s</xliff:g> byderhand."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Geen toestelle gevind nie. Probeer later weer."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth en wi-fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"horlosie"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Kies ’n toestel wat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> moet bestuur"</string> <string name="chooser_title" msgid="2235819929238267637">"Kies ’n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om op te stel"</string> + <string name="single_device_title" msgid="4199861437545438606">"Soek tans vir ’n <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Hierdie app sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, en sal toegang tot hierdie toestemmings op jou <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> hê"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Laat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toe om <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> te bestuur?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"toestel"</string> diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml index a6b78cb6dcb7..e53efcedd8cc 100644 --- a/packages/CompanionDeviceManager/res/values-am/strings.xml +++ b/packages/CompanionDeviceManager/res/values-am/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"አጃቢ የመሣሪያ አስተዳዳሪ"</string> <string name="confirmation_title" msgid="2244241995958340998">"መተግበሪያው <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ን እንዲደርስ ይፈቀድለት?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ይህ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> እንደበራለት ያረጋግጡ እና የእርስዎን <xliff:g id="PROFILE_NAME">%3$s</xliff:g> በአቅራቢያ ያቆዩ።"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ምንም መሣሪያዎች አልተገኙም። እባክዎ ቆይተው እንደገና ይሞክሩ።"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ብሉቱዝ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ብሉቱዝ እና Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ሰዓት"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> የሚያስተዳድረው መሣሪያ ይምረጡ"</string> <string name="chooser_title" msgid="2235819929238267637">"የሚያዋቅሩት <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> በመፈለግ ላይ"</string> <string name="summary_watch" msgid="8134580124808507407">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን እንዲያሰምር እና እነዚህን ፈቃዶች በእርስዎ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ላይ እንዲደርስ ይፈቀድለታል"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ን እንዲያስተዳድር ይፈቅዳሉ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"መሣሪያ"</string> diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml index 5c07f3a16337..efbc6d92981a 100644 --- a/packages/CompanionDeviceManager/res/values-ar/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"تطبيق \"مدير الجهاز المصاحب\""</string> <string name="confirmation_title" msgid="2244241995958340998">"هل تريد السماح لـ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>؟"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"يُرجى التأكّد من أنّ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> مفعَّل في <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>، وجعل <xliff:g id="PROFILE_NAME">%3$s</xliff:g> بالقرب منك."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"لم يتم العثور على أي أجهزة. يُرجى إعادة المحاولة لاحقًا."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"البلوتوث"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"البلوتوث وWi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"الساعة"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"اختيار جهاز ليديره تطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" للإعداد"</string> + <string name="single_device_title" msgid="4199861437545438606">"جارٍ البحث عن <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"سيتم السماح لهذا التطبيق بمزامنة المعلومات، مثلاً اسم المتصل، واستخدام هذه الأذونات على <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"هل تريد السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بإدارة <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>؟"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"جهاز"</string> diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml index c07602afc050..9001a2c5e758 100644 --- a/packages/CompanionDeviceManager/res/values-as/strings.xml +++ b/packages/CompanionDeviceManager/res/values-as/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"কম্পেনিয়ন ডিভাইচ মেনেজাৰ"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> এপ্টোক <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> এক্সেছ কৰিবলৈ দিবনে?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"এই <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>টোৰ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> অন হৈ থকাটো নিশ্চিত কৰক আৰু আপোনাৰ <xliff:g id="PROFILE_NAME">%3$s</xliff:g> আশে-পাশে ৰাখক।"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"কোনো ডিভাইচ বিচাৰি পোৱা নগ’ল। অনুগ্ৰহ কৰি পাছত পুনৰ চেষ্টা কৰক।"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ব্লুটুথ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"ৱাই-ফাই"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ব্লুটুথ আৰু ৱাই-ফাই"</string> <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ী"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>এ পৰিচালনা কৰিবলগীয়া এটা ডিভাইচ বাছনি কৰক"</string> <string name="chooser_title" msgid="2235819929238267637">"ছেট আপ কৰিবলৈ এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string> + <string name="single_device_title" msgid="4199861437545438606">"কোনো <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বিচাৰি থকা হৈছে"</string> <string name="summary_watch" msgid="8134580124808507407">"এই এপ্টোক ফ’ন কৰা লোকৰ নামৰ দৰে তথ্য ছিংক কৰিবলৈ আৰু আপোনাৰ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>ত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> পৰিচালনা কৰিবলৈ দিবনে?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইচ"</string> diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml index f053aa85a28f..2ffe84ead5b0 100644 --- a/packages/CompanionDeviceManager/res/values-az/strings.xml +++ b/packages/CompanionDeviceManager/res/values-az/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Kompanyon Cihaz Meneceri"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazına daxil olmaq icazəsi verilsin?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Bu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> cihazında <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> yandırılmalı və <xliff:g id="PROFILE_NAME">%3$s</xliff:g> yaxınlıqda saxlanılmalıdır."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Cihaz tapılmadı. Sonra cəhd edin."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth və Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"izləyin"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tərəfindən idarə ediləcək cihaz seçin"</string> <string name="chooser_title" msgid="2235819929238267637">"Ayarlamaq üçün <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> axtarılır"</string> <string name="summary_watch" msgid="8134580124808507407">"Bu tətbiq zəng edənin adı kimi məlumatları sinxronlaşdıra, <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> cihazında bu icazələrə daxil ola biləcək"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazını idarə etmək icazəsi verilsin?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"cihazda"</string> diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml index 621ea2102747..ab52c39b34b9 100644 --- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Menadžer pridruženog uređaja"</string> <string name="confirmation_title" msgid="2244241995958340998">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Uverite se da je za <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> uključen <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> i da u blizini imate <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nije pronađen nijedan uređaj. Probajte ponovo kasnije."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WiFi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth i WiFi"</string> <string name="profile_name_watch" msgid="576290739483672360">"sat"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> koji želite da podesite"</string> + <string name="single_device_title" msgid="4199861437545438606">"Traži se <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Ovoj aplikaciji će biti dozvoljeno da sinhronizuje podatke, poput imena pozivaoca, i pristupa tim dozvolama na uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite li da dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string> diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml index 0cdebcdbeffe..884101fe718d 100644 --- a/packages/CompanionDeviceManager/res/values-be/strings.xml +++ b/packages/CompanionDeviceManager/res/values-be/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Менеджар спадарожнай прылады"</string> <string name="confirmation_title" msgid="2244241995958340998">"Дазволіць праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ да прылады <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Упэўніцеся, што на гэтай прыладзе (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) уключаны <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, і трымайце <xliff:g id="PROFILE_NAME">%3$s</xliff:g> паблізу."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Прылады не знойдзены. Паўтарыце спробу пазней."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth і Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"гадзіннік"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Выберыце прыладу (<xliff:g id="APP_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма <strong></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Выберыце імя <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для наладжвання"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>: ідзе пошук"</string> <string name="summary_watch" msgid="8134580124808507407">"Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) на вашай прыладзе тыпу \"<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>\" і атрымае наступныя дазволы"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Дазволіць праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> кіраваць прыладай <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"прылада"</string> diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml index f522ab4807ae..9c3b94e6a0fe 100644 --- a/packages/CompanionDeviceManager/res/values-bg/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Да се разреши ли на приложението <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до устройството <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Функцията за <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> на <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> трябва да е включена и <xliff:g id="PROFILE_NAME">%3$s</xliff:g> да е близо."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Няма намерени устройства. Моля, опитайте отново по-късно."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth и Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Изберете устройство, което да се управлява от <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, за да го настроите"</string> + <string name="single_device_title" msgid="4199861437545438606">"Търси се <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Това приложение ще получи право да синхронизира различна информация, като например името на обаждащия се, и достъп до следните разрешения за вашия <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешавате ли на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управлява устройството <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"устройство"</string> diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml index 61ec8c9bdf28..88db2a5d0975 100644 --- a/packages/CompanionDeviceManager/res/values-bn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> অ্যাক্সেস করার জন্য <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> অ্যাপকে কি অনুমতি দিতে চান?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>-এর <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> চালু আছে কিনা তা ভালোভাবে দেখে নিন এবং আপনার <xliff:g id="PROFILE_NAME">%3$s</xliff:g> কাছাকাছি রাখুন।"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"কোনও ডিভাইস খুঁজে পাওয়া যায়নি। পরে আবার চেষ্টা করুন।"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ব্লুটুথ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"ওয়াই-ফাই"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ব্লুটুথ ও ওয়াই-ফাই"</string> <string name="profile_name_watch" msgid="576290739483672360">"ঘড়ি"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ম্যানেজ করা যাবে এমন একটি ডিভাইস বেছে নিন"</string> <string name="chooser_title" msgid="2235819929238267637">"সেট-আপ করতে কোনও <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> খোঁজা হচ্ছে"</string> <string name="summary_watch" msgid="8134580124808507407">"কল করছেন এমন কোনও ব্যক্তির নামের মতো তথ্য সিঙ্ক ও আপনার <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>-এ এইসব অনুমতি অ্যাক্সেস করার জন্য, এই অ্যাপকে অনুমতি দেওয়া হবে"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"আপনি কি <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ম্যানেজ করার জন্য <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-কে অনুমতি দেবেন?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ডিভাইস"</string> diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml index 00205f257315..e7f9b146133e 100644 --- a/packages/CompanionDeviceManager/res/values-bs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Prateći upravitelj uređaja"</string> <string name="confirmation_title" msgid="2244241995958340998">"Dozvoliti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa uređaju <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Provjerite ima li <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> uključen <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> i približite <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nije pronađen nijedan uređaj. Pokušajte ponovo kasnije."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WiFi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth i WiFi"</string> <string name="profile_name_watch" msgid="576290739483672360">"sat"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da postavite"</string> + <string name="single_device_title" msgid="4199861437545438606">"Traži se <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aplikaciji će biti dozvoljeno da sinhronizira informacije, kao što je ime osobe koja upućuje poziv, i pristupa ovim odobrenjima koje sadržava vaš <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Dozvoliti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string> diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml index 662e297ae00c..8c0b117f29ea 100644 --- a/packages/CompanionDeviceManager/res/values-ca/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestor de dispositius complementaris"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vols permetre que l\'aplicació <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Assegura\'t que aquest dispositiu (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) hagi activat <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> i mantén el <xliff:g id="PROFILE_NAME">%3$s</xliff:g> a prop."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No s\'ha trobat cap dispositiu. Torna-ho a provar més tard."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"el Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"la Wi‑Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"el Bluetooth i la Wi‑Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"rellotge"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Tria un dispositiu perquè el gestioni <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> per configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"S\'està cercant un <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, i accedir a aquests permisos al <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestioni <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositiu"</string> diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml index 6b110d3ae7b1..cde31af7ec97 100644 --- a/packages/CompanionDeviceManager/res/values-cs/strings.xml +++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Správce doprovodných zařízení"</string> <string name="confirmation_title" msgid="2244241995958340998">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Zkontrolujte, zda je na tomto zařízení typu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> zapnutá funkce <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> a mějte své zařízení typu <xliff:g id="PROFILE_NAME">%3$s</xliff:g> poblíž."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nebyla nalezena žádná zařízení. Zkuste to znovu později."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth a Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vyberte zařízení, které chcete spravovat pomocí aplikace <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete nastavit"</string> + <string name="single_device_title" msgid="4199861437545438606">"Vyhledávání zařízení typu <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Tato aplikace bude moct synchronizovat údaje, jako je jméno volajícího, a získat na zařízení typu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> přístup k těmto oprávněním"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> spravovat zařízení <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"zařízení"</string> diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml index bbd01105c538..08a1ae1a8623 100644 --- a/packages/CompanionDeviceManager/res/values-da/strings.xml +++ b/packages/CompanionDeviceManager/res/values-da/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Medfølgende enhedsadministrator"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vil du give appen <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Sørg for, at <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> er aktiveret på denne <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>, og sørg for, at dit <xliff:g id="PROFILE_NAME">%3$s</xliff:g> er i nærheden."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Der blev ikke fundet nogen enheder. Prøv igen senere."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth og Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ur"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vælg en enhed, som skal administreres af <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Vælg en <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, som du vil konfigurere"</string> + <string name="single_device_title" msgid="4199861437545438606">"Søger efter et <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Denne app får tilladelse til at synkronisere oplysninger, f.eks. navne på dem, der ringer, og adgang til disse tilladelser på din <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du tillade, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administrerer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"enhed"</string> diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml index 3eecfe71f6b6..30528c528518 100644 --- a/packages/CompanionDeviceManager/res/values-de/strings.xml +++ b/packages/CompanionDeviceManager/res/values-de/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Begleitgerät-Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Zulassen, dass <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> auf <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> zugreifen darf?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Achte darauf, dass die Option „<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>“ auf diesem <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> aktiviert ist und dein Begleitgerät vom Typ „<xliff:g id="PROFILE_NAME">%3$s</xliff:g>“ in der Nähe ist."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Keine Geräte gefunden. Bitte versuche es später noch einmal."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WLAN"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth & WLAN"</string> <string name="profile_name_watch" msgid="576290739483672360">"Smartwatch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Gerät auswählen, das von <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> verwaltet werden soll"</string> <string name="chooser_title" msgid="2235819929238267637">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> zum Einrichten auswählen"</string> + <string name="single_device_title" msgid="4199861437545438606">"Nach einem Begleitgerät vom Typ „<xliff:g id="PROFILE_NAME">%1$s</xliff:g>“ suchen"</string> <string name="summary_watch" msgid="8134580124808507407">"Diese App darf dann Daten wie den Namen eines Anrufers synchronisieren und auf diese Berechtigungen auf deinem Gerät (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) zugreifen"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zulassen, dass <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> das Gerät <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> verwalten darf?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"Gerät"</string> diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml index a26162f4e077..cffb365974f4 100644 --- a/packages/CompanionDeviceManager/res/values-el/strings.xml +++ b/packages/CompanionDeviceManager/res/values-el/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Διαχείριση συνοδευτικής εφαρμογής"</string> <string name="confirmation_title" msgid="2244241995958340998">"Να επιτρέπεται στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να έχει πρόσβαση στη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>;"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Βεβαιωθείτε ότι αυτή η συσκευή <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> έχει ενεργοποιημένο το <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> και κρατήστε τη συσκευή <xliff:g id="PROFILE_NAME">%3$s</xliff:g> κοντά."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Δεν βρέθηκαν συσκευές. Δοκιμάστε ξανά αργότερα."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth και Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ρολόι"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Επιλέξτε μια συσκευή για διαχείριση μέσω της εφαρμογής <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για ρύθμιση"</string> + <string name="single_device_title" msgid="4199861437545438606">"Αναζήτηση για <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες, όπως το όνομα ενός ατόμου που σας καλεί, και να αποκτά πρόσβαση σε αυτές τις άδειες στη συσκευή <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Να επιτρέπεται στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να διαχειρίζεται τη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ;"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"συσκευή"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml index b5fea9f22c15..8590e9f96f1c 100644 --- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Allow the app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Make sure that this <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> has <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> turned on and keep your <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nearby."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No devices found. Please try again later."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth and Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string> + <string name="single_device_title" msgid="4199861437545438606">"Looking for a <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml index 42c6b888cddc..041966ec0ce4 100644 --- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Allow the app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Make sure this <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> has <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> turned on, and keep your <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nearby."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No devices found. Please try again later."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth and Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string> + <string name="single_device_title" msgid="4199861437545438606">"Looking for a <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml index b5fea9f22c15..8590e9f96f1c 100644 --- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Allow the app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Make sure that this <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> has <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> turned on and keep your <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nearby."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No devices found. Please try again later."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth and Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string> + <string name="single_device_title" msgid="4199861437545438606">"Looking for a <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string> diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml index b5fea9f22c15..8590e9f96f1c 100644 --- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Allow the app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Make sure that this <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> has <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> turned on and keep your <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nearby."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No devices found. Please try again later."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth and Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"watch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choose a device to be managed by <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to set up"</string> + <string name="single_device_title" msgid="4199861437545438606">"Looking for a <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"This app will be allowed to sync info, like the name of someone calling, and access these permissions on your <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string> diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml index a5d00a3186e0..88ae3ed0356b 100644 --- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Administrador de dispositivo complementario"</string> <string name="confirmation_title" msgid="2244241995958340998">"¿Quieres permitir que la app de <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Asegúrate de que este <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> tenga activado el <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> y mantén cerca tu <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No se encontraron dispositivos. Vuelve a intentarlo más tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth y Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Elige un dispositivo para que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> lo administre"</string> <string name="chooser_title" msgid="2235819929238267637">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"Buscando un <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Esta app podrá sincronizar información, como el nombre de alguien cuando te llame, y acceder a los siguientes permisos en tu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administre <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml index fc6e6c55557a..ac8c79a61496 100644 --- a/packages/CompanionDeviceManager/res/values-es/strings.xml +++ b/packages/CompanionDeviceManager/res/values-es/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos complementario"</string> <string name="confirmation_title" msgid="2244241995958340998">"¿Permitir que la aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Asegúrate de que este dispositivo (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) tenga el <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> activado y mantén tu <xliff:g id="PROFILE_NAME">%3$s</xliff:g> cerca."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"No se ha encontrado ningún dispositivo. Inténtalo de nuevo más tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth y Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloj"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Elige un dispositivo para que lo gestione <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Elige el <xliff:g id="PROFILE_NAME">%1$s</xliff:g> que quieras configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"Buscando <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Esta aplicación podrá sincronizar información, como el nombre de la persona que llama, y acceder a estos permisos de tu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"¿Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestione <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml index 2cbb44134d31..9c22847df868 100644 --- a/packages/CompanionDeviceManager/res/values-et/strings.xml +++ b/packages/CompanionDeviceManager/res/values-et/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Kaasseadme haldur"</string> <string name="confirmation_title" msgid="2244241995958340998">"Kas anda rakendusele <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> juurdepääs seadmele <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Veenduge, et seadmes <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> oleks <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> sisse lülitatud, ja hoidke oma seade <xliff:g id="PROFILE_NAME">%3$s</xliff:g> läheduses."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Seadmeid ei leitud. Proovige hiljem uuesti."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WiFi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth ja WiFi"</string> <string name="profile_name_watch" msgid="576290739483672360">"käekell"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Valige seade, mida haldab rakendus <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Valige <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mis seadistada"</string> + <string name="single_device_title" msgid="4199861437545438606">"Seadme <xliff:g id="PROFILE_NAME">%1$s</xliff:g> otsimine"</string> <string name="summary_watch" msgid="8134580124808507407">"Sellel rakendusel lubatakse sünkroonida teavet (nt helistaja nime) ja antakse juurdepääs nendele lubadele, mille asukoht on teie <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hallata seadet <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"seade"</string> diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml index 3a49cf94ca6b..c52c2b982f02 100644 --- a/packages/CompanionDeviceManager/res/values-eu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gailu osagarriaren kudeatzailea"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> gailua erabiltzeko baimena eman nahi diozu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Ziurtatu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> honen <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> aktibatuta dagoela, eta eduki <xliff:g id="PROFILE_NAME">%3$s</xliff:g> hurbil."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Ez da aurkitu gailurik. Saiatu berriro geroago."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetootha"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wifia"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetootha eta wifia"</string> <string name="profile_name_watch" msgid="576290739483672360">"erlojua"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Aukeratu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioak kudeatu behar duen gailua"</string> <string name="chooser_title" msgid="2235819929238267637">"Aukeratu konfiguratu nahi duzun <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> baten bila"</string> <string name="summary_watch" msgid="8134580124808507407">"Informazioa sinkronizatzeko (esate baterako, deitzaileen izenak) eta hauetarako baimenak izango ditu aplikazioak <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> erabiltzean:"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> kudeatzeko baimena eman nahi diozu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"gailua"</string> diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml index 481522500140..2f4f9380171e 100644 --- a/packages/CompanionDeviceManager/res/values-fa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"مدیر دستگاه مرتبط"</string> <string name="confirmation_title" msgid="2244241995958340998">"به برنامه <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه داده شود به <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> دسترسی پیدا کند؟"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"مطمئن شوید <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> در این <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> روشن باشد و <xliff:g id="PROFILE_NAME">%3$s</xliff:g> را نزدیک نگه دارید."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"دستگاهی پیدا نشد. لطفاً بعداً دوباره امتحان کنید."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"بلوتوث"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"بلوتوث و Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ساعت"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"انتخاب دستگاه برای مدیریت کردن با <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای راهاندازی"</string> + <string name="single_device_title" msgid="4199861437545438606">"درحال یافتن <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"به این برنامه اجازه داده میشود اطلاعاتی مثل نام تماسگیرنده را همگامسازی کند و به این اجازهها در <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> شما دسترسی داشته باشد"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه داده شود <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> را مدیریت کند؟"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"دستگاه"</string> diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml index 6e13d6cf542e..be4076abde4b 100644 --- a/packages/CompanionDeviceManager/res/values-fi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Sallitaanko, että soellus (<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>) saa pääsyn laitteeseen: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Varmista, että <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> on päällä laitteella (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>), ja pidä <xliff:g id="PROFILE_NAME">%3$s</xliff:g> lähellä."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Laitteita ei löydy. Yritä myöhemmin uudelleen."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth ja Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"kello"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Valitse laite, jota <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hallinnoi"</string> <string name="chooser_title" msgid="2235819929238267637">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, niin voit suorittaa käyttöönoton"</string> + <string name="single_device_title" msgid="4199861437545438606">"Etsitään tätä: <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Sovellus saa luvan synkronoida tietoja (esimerkiksi soittajan nimen) ja pääsyn näihin lupiin laitteella (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa ylläpitää laitetta: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"laite"</string> diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml index 73a180b586d3..0aa462bee90e 100644 --- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareil compagnon"</string> <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'appli <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Assurez-vous que le <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> est activé sur cet appareil (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) et gardez votre <xliff:g id="PROFILE_NAME">%3$s</xliff:g> à proximité."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Aucun appareil détecté. Veuillez réessayer plus tard."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth et Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"montre"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choisir un appareil qui sera géré par <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Choisir un appareil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) pour le configurer"</string> + <string name="single_device_title" msgid="4199861437545438606">"À la recherche de l\'appareil suivant : <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Cette appli sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à gérer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string> diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml index 0c0ae7912dc4..e7741c42850e 100644 --- a/packages/CompanionDeviceManager/res/values-fr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestionnaire d\'appareils associés"</string> <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'appli <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Assurez-vous que le <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> de votre <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> est activé et gardez votre <xliff:g id="PROFILE_NAME">%3$s</xliff:g> à proximité."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Aucun appareil trouvé. Veuillez réessayer plus tard."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth et Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"montre"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Sélectionner l\'appareil qui sera géré par <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Sélectionner votre <xliff:g id="PROFILE_NAME">%1$s</xliff:g> à configurer"</string> + <string name="single_device_title" msgid="4199861437545438606">"Recherche de l\'appareil suivant : <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Cette appli sera autorisée à synchroniser des infos (comme le nom de l\'appelant) et disposera de ces autorisations sur votre <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à gérer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string> diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml index 71eb86ff32f3..bf58761da26f 100644 --- a/packages/CompanionDeviceManager/res/values-gl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Xestor de dispositivos complementarios"</string> <string name="confirmation_title" msgid="2244241995958340998">"Queres permitir que a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda ao dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Cómpre que este <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> teña activada a conexión <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> e que estea preto do <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Non se atopou ningún dispositivo. Téntao de novo máis tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wifi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e wifi"</string> <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolle un dispositivo para que o xestione a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Escolle o perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) que queiras configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"Buscando <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) e acceder a estes permisos do dispositivo (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Queres permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> xestione o dispositivo (<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>)?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml index 9b20886bc0af..d3db96eedb6b 100644 --- a/packages/CompanionDeviceManager/res/values-gu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"કમ્પેનિયન ડિવાઇસ મેનેજર"</string> <string name="confirmation_title" msgid="2244241995958340998">"શું <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ને ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ઍપને મંજૂરી આપીએ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ખાતરી કરો કે આ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> દ્વારા <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ચાલુ કરવામાં આવી છે અને તમારી <xliff:g id="PROFILE_NAME">%3$s</xliff:g> નજીકમાં રાખો."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"કોઈ ડિવાઇસ મળ્યું નથી. કૃપા કરીને થોડા સમય પછી ફરી પ્રયાસ કરો."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"બ્લૂટૂથ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"વાઇ-ફાઇ"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"બ્લૂટૂથ અને વાઇ-ફાઇ"</string> <string name="profile_name_watch" msgid="576290739483672360">"સ્માર્ટવૉચ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> દ્વારા મેનેજ કરવા માટે કોઈ ડિવાઇસ પસંદ કરો"</string> <string name="chooser_title" msgid="2235819929238267637">"સેટઅપ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> શોધી રહ્યાં છીએ"</string> <string name="summary_watch" msgid="8134580124808507407">"આ ઍપને, કૉલ કરનાર વ્યક્તિનું નામ જેવી માહિતી સિંક કરવાની અને તમારા <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> મેનેજ કરવા માટે મંજૂરી આપીએ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ડિવાઇસ"</string> diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml index 7224896392e4..2d38a00e9fcb 100644 --- a/packages/CompanionDeviceManager/res/values-hi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"कंपैनियन डिवाइस मैनेजर"</string> <string name="confirmation_title" msgid="2244241995958340998">"क्या <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> को ऐक्सेस करने के लिए <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ऐप्लिकेशन को अनुमति देनी है?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"पक्का करें कि इस <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> का <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> चालू हो और <xliff:g id="PROFILE_NAME">%3$s</xliff:g> आपके आस-पास हो."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"कोई डिवाइस नहीं मिला. कृपया बाद में कोशिश करें."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ब्लूटूथ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"वाई-फ़ाई"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ब्लूटूथ और वाई-फ़ाई"</string> <string name="profile_name_watch" msgid="576290739483672360">"स्मार्टवॉच"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> से मैनेज किया जाने वाला डिवाइस चुनें"</string> <string name="chooser_title" msgid="2235819929238267637">"सेट अप करने के लिए कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> को ढूंढा जा रहा है"</string> <string name="summary_watch" msgid="8134580124808507407">"यह ऐप्लिकेशन, आपके <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> पर इन अनुमतियों को ऐक्सेस करने के साथ-साथ कॉल करने वाले व्यक्ति के नाम जैसी जानकारी सिंक कर पाएगा"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"क्या <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> मैनेज करने की अनुमति देनी है?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"डिवाइस"</string> diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml index 0b769f036f32..d002c9ce0f82 100644 --- a/packages/CompanionDeviceManager/res/values-hr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Upravitelj popratnih uređaja"</string> <string name="confirmation_title" msgid="2244241995958340998">"Želite li dopustiti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Provjerite je li na uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> uključen <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> i držite <xliff:g id="PROFILE_NAME">%3$s</xliff:g> u blizini."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nije pronađen nijedan uređaj. Pokušajte ponovo kasnije."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth i Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"satom"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Odaberite uređaj kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Odaberite profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> koji želite postaviti"</string> + <string name="single_device_title" msgid="4199861437545438606">"Traži se <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aplikacija će moći sinkronizirati podatke kao što je ime pozivatelja i pristupiti tim dopuštenjima na vašem uređaju <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Dopustiti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"uređaj"</string> diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml index 69bd41b28f63..8b11dac56f9c 100644 --- a/packages/CompanionDeviceManager/res/values-hu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Társeszközök kezelője"</string> <string name="confirmation_title" msgid="2244241995958340998">"Engedélyezi a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazás számára, hogy hozzáférjen a következőhöz: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Győződjön meg arról, hogy a <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> be van kapcsolva ezen a(z) <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> eszközön, és hogy a(z) <xliff:g id="PROFILE_NAME">%3$s</xliff:g> eszköz a közelben van."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nem található eszköz. Próbálja újra később."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth és Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"óra"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"A(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> alkalmazással kezelni kívánt eszköz kiválasztása"</string> <string name="chooser_title" msgid="2235819929238267637">"Válassza ki a beállítani kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> nevet."</string> + <string name="single_device_title" msgid="4199861437545438606">"Keresés – <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Ez az alkalmazás képes lesz szinkronizálni információkat (például a hívó fél nevét), és hozzáférhet majd ezekhez az engedélyekhez a következőn: <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Engedélyezi, hogy a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> kezelje a következő eszközt: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"eszköz"</string> diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml index 27cd9751d824..9d45928eeb5f 100644 --- a/packages/CompanionDeviceManager/res/values-hy/strings.xml +++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Թույլատրե՞լ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին կառավարել <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> սարքը"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Համոզվեք, որ այս <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> սարքի <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>-ը միացված է, և ձեր <xliff:g id="PROFILE_NAME">%3$s</xliff:g>-ը մոտ պահեք։"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Սարքեր չեն գտնվել։ Փորձեք ավելի ուշ։"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth և Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ժամացույց"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Ընտրեք սարքը, որը պետք է կառավարվի <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածի միջոցով"</string> <string name="chooser_title" msgid="2235819929238267637">"Կարգավորելու համար ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> սարքի որոնում"</string> <string name="summary_watch" msgid="8134580124808507407">"Այս հավելվածը կկարողանա համաժամացնել տվյալները, օր․՝ զանգողի անունը, և կստանա հետևյալ թույլտվությունները ձեր <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>ում"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Թույլատրե՞լ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին կառավարել <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> սարքը"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"սարք"</string> diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml index 6ec3392a02ad..9c9144c4f63d 100644 --- a/packages/CompanionDeviceManager/res/values-in/strings.xml +++ b/packages/CompanionDeviceManager/res/values-in/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Pengelola Perangkat Pendamping"</string> <string name="confirmation_title" msgid="2244241995958340998">"Izinkan aplikasi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Pastikan <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ini mengaktifkan <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, dan letakkan <xliff:g id="PROFILE_NAME">%3$s</xliff:g> di dekat Anda."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Perangkat tidak ditemukan. Coba lagi nanti."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth dan Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pilih perangkat untuk dikelola oleh <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk disiapkan"</string> + <string name="single_device_title" msgid="4199861437545438606">"Mencari <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aplikasi ini akan diizinkan menyinkronkan info, seperti nama penelepon, dan mengakses izin ini di <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> Anda"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengelola <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"perangkat"</string> diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml index f1b6ced64d69..1247aaef319f 100644 --- a/packages/CompanionDeviceManager/res/values-is/strings.xml +++ b/packages/CompanionDeviceManager/res/values-is/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Stjórnun fylgdartækja"</string> <string name="confirmation_title" msgid="2244241995958340998">"Veita forritinu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Gakktu úr skugga um að kveikt sé á <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> í <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> og hafðu <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nálægt."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Engin tæki fundust. Reyndu aftur síðar."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth og Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"úr"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Veldu tæki sem <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> á að stjórna"</string> <string name="chooser_title" msgid="2235819929238267637">"Veldu <xliff:g id="PROFILE_NAME">%1$s</xliff:g> til að setja upp"</string> + <string name="single_device_title" msgid="4199861437545438606">"Leitar að <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Þetta forrit fær heimild til að samstilla upplýsingar, t.d. nafn þess sem hringir, og fær aðgang að eftirfarandi heimildum í <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Leyfa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> að stjórna <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"tæki"</string> diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml index 2afdcbaab8bf..3fa0419832e8 100644 --- a/packages/CompanionDeviceManager/res/values-it/strings.xml +++ b/packages/CompanionDeviceManager/res/values-it/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestione dispositivi associati"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vuoi consentire all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Assicurati che il <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> abbia il <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> attivo e tieni l’<xliff:g id="PROFILE_NAME">%3$s</xliff:g> vicino."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nessun dispositivo trovato. Riprova più tardi."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"orologio"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Scegli un dispositivo che sia gestito da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da configurare"</string> + <string name="single_device_title" msgid="4199861437545438606">"Ricerca di un <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, e accedere alle seguenti autorizzazioni <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vuoi consentire all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di gestire <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml index 4181e6278d4f..f775a7f16f81 100644 --- a/packages/CompanionDeviceManager/res/values-iw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string> <string name="confirmation_title" msgid="2244241995958340998">"לאפשר לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת אל <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"צריך לוודא שה-<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> מופעל ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>, ושה<xliff:g id="PROFILE_NAME">%3$s</xliff:g> בקרבת מקום."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"לא נמצאו מכשירים. אפשר לנסות שוב מאוחר יותר."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"חיבור Wi-Fi ו-Bluetooth"</string> <string name="profile_name_watch" msgid="576290739483672360">"שעון"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"בחירה של מכשיר לניהול באמצעות <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"בחירת <xliff:g id="PROFILE_NAME">%1$s</xliff:g> להגדרה"</string> + <string name="single_device_title" msgid="4199861437545438606">"מתבצע חיפוש של <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, ולגשת להרשאות האלה ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> שלך"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"מתן הרשאה לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong&g; לנהל את <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"מכשיר"</string> diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml index 5974c6b1679c..0ad41cd72916 100644 --- a/packages/CompanionDeviceManager/res/values-ja/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"コンパニオン デバイス マネージャー"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> アプリに <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> へのアクセスを許可しますか?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"この<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>の<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>が ON であることを確認し、<xliff:g id="PROFILE_NAME">%3$s</xliff:g>を近くに置いてください。"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"デバイスが見つかりません。しばらくしてからもう一度お試しください。"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth、Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ウォッチ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> の管理対象となるデバイスの選択"</string> <string name="chooser_title" msgid="2235819929238267637">"設定する<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>を探しています"</string> <string name="summary_watch" msgid="8134580124808507407">"このアプリは、通話相手の名前などの情報を同期したり、<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>の以下の権限にアクセスしたりできるようになります"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> の管理を許可しますか?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"デバイス"</string> diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml index de1c8e1a19b7..d9bc50a4f9f5 100644 --- a/packages/CompanionDeviceManager/res/values-ka/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"კომპანიონი მოწყობილობების მენეჯერი"</string> <string name="confirmation_title" msgid="2244241995958340998">"ნებას რთავთ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს, წვდომა ჰქონდეს <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> მოწყობილობაზე?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"დარწმუნდით, რომ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>-ზე ჩართულია <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> და <xliff:g id="PROFILE_NAME">%3$s</xliff:g> იქონიეთ ახლოს."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"მოწყობილობები ვერ მოიძებნა. ცადეთ მოგვიანებით."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth და Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"საათი"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"აირჩიეთ მოწყობილობა, რომელიც უნდა მართოს <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპმა"</string> <string name="chooser_title" msgid="2235819929238267637">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> დასაყენებლად"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-ის ძებნა"</string> <string name="summary_watch" msgid="8134580124808507407">"ეს აპი შეძლებს ინფორმაციის (მაგალითად, იმ ადამიანის სახელი, რომელიც გირეკავთ) სინქრონიზებას და თქვენს <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>-ზე არსებულ ამ ნებართვებზე წვდომას"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"ნება დართეთ <strong><xliff:g id="APP_NAME">%1$s</xliff:g>-ს</strong> მართოს <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"მოწყობილობა"</string> diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml index 27492a035e8a..2fd8d96dfd7f 100644 --- a/packages/CompanionDeviceManager/res/values-kk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? құрылғысына кіруге рұқсат беріңіз"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Құрылғыдағы (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> қосулы болуын тексеріп, <xliff:g id="PROFILE_NAME">%3$s</xliff:g> құрылғысын маңайында ұстаңыз."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Ешқандай құрылғы табылмады. Кейінірек қайталап көріңіз."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth және Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"сағат"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> арқылы басқарылатын құрылғыны таңдаңыз"</string> <string name="chooser_title" msgid="2235819929238267637">"Реттеу үшін <xliff:g id="PROFILE_NAME">%1$s</xliff:g> таңдаңыз"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын іздеу"</string> <string name="summary_watch" msgid="8134580124808507407">"Бұл қолданба қоңырау шалушының аты сияқты деректі синхрондай алады және құрылғыдағы (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) осы рұқсаттарды пайдалана алады."</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> құрылғысын басқаруға рұқсат беру керек пе?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"құрылғы"</string> diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml index 55216e590683..77e2396cd3c9 100644 --- a/packages/CompanionDeviceManager/res/values-km/strings.xml +++ b/packages/CompanionDeviceManager/res/values-km/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"កម្មវិធីគ្រប់គ្រងឧបករណ៍ដៃគូ"</string> <string name="confirmation_title" msgid="2244241995958340998">"អនុញ្ញាតឱ្យកម្មវិធី <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ឬ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"សូមប្រាកដថា<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>នេះបានបើក<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> និងទុក<xliff:g id="PROFILE_NAME">%3$s</xliff:g>នៅជិតអ្នក។"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"រកមិនឃើញឧបករណ៍ទេ។ សូមព្យាយាមម្ដងទៀតនៅពេលក្រោយ។"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ប៊្លូធូស"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ប៊្លូធូស និង Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"នាឡិកា"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"ជ្រើសរើសឧបករណ៍ ដើម្បីដាក់ក្រោមការគ្រប់គ្រងរបស់ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីរៀបចំ"</string> + <string name="single_device_title" msgid="4199861437545438606">"កំពុងស្វែងរក<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"កម្មវិធីនេះនឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើសមកាលកម្មព័ត៌មាន ដូចជាឈ្មោះមនុស្សដែលហៅទូរសព្ទជាដើម និងចូលប្រើការអនុញ្ញាតទាំងនេះនៅលើ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> របស់អ្នក"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> គ្រប់គ្រង <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ឬ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ឧបករណ៍"</string> diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml index 7dcb4e379637..8320708da102 100644 --- a/packages/CompanionDeviceManager/res/values-kn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ಕಂಪ್ಯಾನಿಯನ್ ಸಾಧನ ನಿರ್ವಾಹಕರು"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ಈ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ನಲ್ಲಿ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ಆನ್ ಆಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ ಮತ್ತು ನಿಮ್ಮ <xliff:g id="PROFILE_NAME">%3$s</xliff:g> ಅನ್ನು ಸಮೀಪಲ್ಲಿಡಿ."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ಯಾವುದೇ ಸಾಧನಗಳು ಕಂಡುಬಂದಿಲ್ಲ. ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ಬ್ಲೂಟೂತ್"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"ವೈ-ಫೈ"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ಬ್ಲೂಟೂತ್ ಮತ್ತು ವೈ-ಫೈ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ವೀಕ್ಷಿಸಿ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ ಸಾಧನವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="chooser_title" msgid="2235819929238267637">"ಸೆಟಪ್ ಮಾಡಲು <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆರಿಸಿ"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string> <string name="summary_watch" msgid="8134580124808507407">"ಯಾರೋ ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಮತ್ತು <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ನಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸಲಾಗುತ್ತದೆ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? ನಿರ್ವಹಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ಸಾಧನ"</string> diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml index ff8ed1638062..ee4db7d681ad 100644 --- a/packages/CompanionDeviceManager/res/values-ko/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"부속 기기 관리자"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 앱에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>에 액세스하도록 허용하시겠습니까?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"이 <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>에서 <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> 기능을 사용 설정하고 <xliff:g id="PROFILE_NAME">%3$s</xliff:g> 기기를 근처에 두세요."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"기기를 찾을 수 없습니다. 나중에 다시 시도해 주세요."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"블루투스"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"블루투스 및 Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"시계"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 관리할 기기 선택"</string> <string name="chooser_title" msgid="2235819929238267637">"설정할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 선택"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> 찾는 중"</string> <string name="summary_watch" msgid="8134580124808507407">"이 앱이 정보(예: 발신자 이름)를 동기화하고 <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>에서 이러한 권한에 액세스할 수 있게 됩니다."</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> 기기를 관리하도록 허용하시겠습니까?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"기기"</string> diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml index 8c39dd2dea6f..af01cf7c8d7d 100644 --- a/packages/CompanionDeviceManager/res/values-ky/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгүнө кирүүгө уруксат бересизби?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> түзмөгүңүздөгү <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>ыкмасын күйгүзүп, <xliff:g id="PROFILE_NAME">%3$s</xliff:g> профилиңизди жакын кармаңыз."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Түзмөктөр табылган жок. Кийинчерээк кайталап көрүңүз."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth жана Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"саат"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> аркылуу башкарыла турган түзмөктү тандаңыз"</string> <string name="chooser_title" msgid="2235819929238267637">"Тууралоо үчүн <xliff:g id="PROFILE_NAME">%1$s</xliff:g> тандаңыз"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> профилин издөө"</string> <string name="summary_watch" msgid="8134580124808507407">"Бул колдонмого маалыматты, мисалы, чалып жаткан адамдын аты-жөнүн шайкештирүүгө жана <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> түзмөгүңүздө төмөнкүлөрдү аткарууга уруксат берилет"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгүн тескөөгө уруксат бересизби?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"түзмөк"</string> diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml index a7cc51e55c2d..d7f777d3c8f1 100644 --- a/packages/CompanionDeviceManager/res/values-lo/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ຕົວຈັດການອຸປະກອນປະກອບ"</string> <string name="confirmation_title" msgid="2244241995958340998">"ອະນຸຍາດໃຫ້ແອັບ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ເຂົ້າເຖິງ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ບໍ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ກວດສອບໃຫ້ໝັ້ນໃຈວ່າ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ເຄື່ອງນີ້ເປີດ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ຢູ່ ແລະ ໃຫ້ຢູ່ໃກ້ກັບ <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ບໍ່ພົບອຸປະກອນ. ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth ແລະ Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ໂມງ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"ເລືອກອຸປະກອນທີ່ຈະໃຫ້ມີການຈັດການໂດຍ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ທີ່ຈະຕັ້ງຄ່າ"</string> + <string name="single_device_title" msgid="4199861437545438606">"ກຳລັງຊອກຫາ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"ແອັບນີ້ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ຊິ້ງຂໍ້ມູນ ເຊັ່ນ: ຊື່ຂອງຄົນທີ່ໂທເຂົ້າ ແລະ ສິດເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ຂອງທ່ານ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ຈັດການ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ບໍ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ອຸປະກອນ"</string> diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml index b537508b8f7b..9fcf0fa22c67 100644 --- a/packages/CompanionDeviceManager/res/values-lt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Leisti programai <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Įsitikinkite, kad šiame įrenginyje (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) įjungta <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ir kad <xliff:g id="PROFILE_NAME">%3$s</xliff:g> yra netoliese."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nerasta jokių įrenginių. Vėliau bandykite dar kartą."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"„Bluetooth“ ir „Wi-Fi“"</string> <string name="profile_name_watch" msgid="576290739483672360">"laikrodį"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Įrenginio, kuris bus valdomas naudojant programą <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>, pasirinkimas"</string> <string name="chooser_title" msgid="2235819929238267637">"Norimo nustatyti <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pasirinkimas"</string> + <string name="single_device_title" msgid="4199861437545438606">"Ieškoma <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Šiai programai bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, ir pasiekti toliau nurodytus <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> leidimus"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> valdyti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"įrenginio"</string> diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml index e310fe2ca887..39b158d58666 100644 --- a/packages/CompanionDeviceManager/res/values-lv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Palīgierīču pārzinis"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vai atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt lietotnei <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Noteikti ieslēdziet šajā ierīcē (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> un gādājiet, lai <xliff:g id="PROFILE_NAME">%3$s</xliff:g> būtu tuvumā."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nav atrasta neviena ierīce. Lūdzu, vēlāk mēģiniet vēlreiz."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi‑Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth un Wi‑Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"pulkstenis"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Izvēlieties ierīci, ko pārvaldīt lietotnē <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Jāizvēlas <xliff:g id="PROFILE_NAME">%1$s</xliff:g> iestatīšanai"</string> + <string name="single_device_title" msgid="4199861437545438606">"Tiek meklēta ierīce (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>)…"</string> <string name="summary_watch" msgid="8134580124808507407">"Šī lietotne drīkstēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, un piekļūt šīm <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> atļaujām."</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vai atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt ierīcei <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ierīce"</string> diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml index 08b422bc12cf..107895d5a8da 100644 --- a/packages/CompanionDeviceManager/res/values-mk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Дозволувате апликацијата <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Погрижете се <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> да биде вклучен на овој <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> и вашиот <xliff:g id="PROFILE_NAME">%3$s</xliff:g> да биде во близина."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Не се најдени уреди. Обидете се повторно подоцна."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth и Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"часовник"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Изберете уред со којшто ќе управува <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> за поставување"</string> + <string name="single_device_title" msgid="4199861437545438606">"Се бара <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Оваа апликација ќе има дозвола да ги синхронизира податоците како што се имињата на јавувачите и да пристапува до следниве дозволи на вашиот <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Ќе дозволите <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управува со <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"уред"</string> diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml index ab9671ed540f..de50fc721522 100644 --- a/packages/CompanionDeviceManager/res/values-ml/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"കമ്പാനിയൻ ഉപകരണ മാനേജർ"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്ന ആപ്പിനെ അനുവദിക്കണോ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ഈ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> എന്നതിൽ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ഓണാക്കിയിട്ടുണ്ടെന്ന് ഉറപ്പുവരുത്തുക, നിങ്ങളുടെ <xliff:g id="PROFILE_NAME">%3$s</xliff:g> സമീപം വയ്ക്കുക."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ഉപകരണങ്ങളൊന്നും കണ്ടെത്തിയില്ല. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"വൈഫൈ"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth-ഉം വൈഫൈയും"</string> <string name="profile_name_watch" msgid="576290739483672360">"വാച്ച്"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു ഉപകരണം തിരഞ്ഞെടുക്കുക"</string> <string name="chooser_title" msgid="2235819929238267637">"സജ്ജീകരിക്കാൻ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരയുകയാണ്"</string> <string name="summary_watch" msgid="8134580124808507407">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കാനും നിങ്ങളുടെ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> എന്നതിൽ ഈ അനുമതികൾ ആക്സസ് ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കും"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? മാനേജ് ചെയ്യാൻ, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ഉപകരണം"</string> diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml index 7b0a08ae1aca..e76f68843f59 100644 --- a/packages/CompanionDeviceManager/res/values-mn/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-д <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> аппыг хандахыг зөвшөөрөх үү?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Энэ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>-д <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>-г асаасан эсэхийг нягталж, өөрийн <xliff:g id="PROFILE_NAME">%3$s</xliff:g>-г ойр байлгана уу."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Ямар ч төхөөрөмж олдсонгүй. Дараа дахин оролдоно уу."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth, Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"цаг"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-н удирдах төхөөрөмжийг сонгоно уу"</string> <string name="chooser_title" msgid="2235819929238267637">"Тохируулахын тулд <xliff:g id="PROFILE_NAME">%1$s</xliff:g> сонгоно уу"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г хайж байна"</string> <string name="summary_watch" msgid="8134580124808507407">"Энэ аппад залгаж буй хэн нэгний нэр зэрэг мэдээллийг синк хийх болон таны <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> дээрх эдгээр зөвшөөрөлд хандахыг зөвшөөрнө"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-г удирдахыг зөвшөөрөх үү?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"төхөөрөмж"</string> diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml index e18f86e5cdfb..722156213623 100644 --- a/packages/CompanionDeviceManager/res/values-mr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"सहयोगी डिव्हाइस व्यवस्थापक"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> अॅपला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> अॅक्सेस करण्याची अनुमती द्यायची आहे का?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"या <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> चे <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> सुरू असल्याची खात्री करा आणि तुमचे<xliff:g id="PROFILE_NAME">%3$s</xliff:g> जवळ ठेवा."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"डिव्हाइस आढळली नाहीत. कृपया नंतर पुन्हा प्रयत्न करा."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ब्लूटूथ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"वाय-फाय"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ब्लूटूथ आणि वाय-फाय"</string> <string name="profile_name_watch" msgid="576290739483672360">"वॉच"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> द्वारे व्यवस्थापित करण्यासाठी डिव्हाइस निवडा"</string> <string name="chooser_title" msgid="2235819929238267637">"सेट करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> शोधत आहे"</string> <string name="summary_watch" msgid="8134580124808507407">"या अॅपला कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करण्याची आणि तुमच्या <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> वर पुढील परवानग्या अॅक्सेस करण्याची अनुमती दिली जाईल"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> व्यवस्थापित करण्याची अनुमती द्यायची आहे?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"डिव्हाइस"</string> diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml index 31cb3b756c6f..ca41c6fe58d2 100644 --- a/packages/CompanionDeviceManager/res/values-ms/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Pengurus Peranti Rakan"</string> <string name="confirmation_title" msgid="2244241995958340998">"Benarkan apl <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Pastikan <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> telah dihidupkan pada <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ini dan pastikan <xliff:g id="PROFILE_NAME">%3$s</xliff:g> berada berdekatan."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Tiada peranti ditemukan. Sila cuba sebentar lagi."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth dan Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"jam tangan"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pilih peranti untuk diurus oleh <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk disediakan"</string> + <string name="single_device_title" msgid="4199861437545438606">"Mencari <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Apl ini akan dibenarkan untuk menyegerakkan maklumat, seperti nama individu yang membuat panggilan dan mengakses kebenaran ini pada <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> anda"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengurus <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"peranti"</string> diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml index 0b0273f67aae..f03048bbc997 100644 --- a/packages/CompanionDeviceManager/res/values-my/strings.xml +++ b/packages/CompanionDeviceManager/res/values-my/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"တွဲဖက်ကိရိယာ မန်နေဂျာ"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကို သုံးရန် <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အက်ပ်ကို ခွင့်ပြုမလား။"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ဤ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> သည် <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ဖွင့်ထားပြီး သင့် <xliff:g id="PROFILE_NAME">%3$s</xliff:g> အနီးတွင်ရှိကြောင်း သေချာပါစေ။"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"မည်သည့်စက်မျှ မတွေ့ပါ။ နောက်မှ ထပ်စမ်းကြည့်ပါ။"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ဘလူးတုသ်"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ဘလူးတုသ်၊ Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"နာရီ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> က စီမံခန့်ခွဲရန် စက်တစ်ခုကို ရွေးပါ"</string> <string name="chooser_title" msgid="2235819929238267637">"စနစ်ထည့်သွင်းရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးပါ"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရှာနေသည်"</string> <string name="summary_watch" msgid="8134580124808507407">"ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်နှင့် သင့် <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> တွင် ၎င်းခွင့်ပြုချက်များရယူရန် ဤအက်ပ်ကိုခွင့်ပြုမည်"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကို <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အား စီမံခွင့်ပြုမလား။"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"စက်"</string> diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml index ccb2c572f6f7..1d62349da406 100644 --- a/packages/CompanionDeviceManager/res/values-nb/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vil du gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-appen tilgang til <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Sørg for at <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> har <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> slått på, og hold <xliff:g id="PROFILE_NAME">%3$s</xliff:g> i nærheten."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Fant ingen enheter. Prøv på nytt senere."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wifi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth og wifi"</string> <string name="profile_name_watch" msgid="576290739483672360">"klokke"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Velg en enhet som skal administreres av <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal konfigureres"</string> + <string name="single_device_title" msgid="4199861437545438606">"Ser etter en <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Denne appen får tillatelse til å synkronisere informasjon, for eksempel navnet til folk som ringer, og har disse tillatelsene på <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du la <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administrere <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"enheten"</string> diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml index 203eaeedbd4c..b363c4bdcfbb 100644 --- a/packages/CompanionDeviceManager/res/values-ne/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"सहयोगी डिभाइसको प्रबन्धक"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> एपलाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> प्रयोग गर्ने अनुमति दिने हो?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"यो <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> को <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> अन गरिएको छ भन्ने कुरा सुनिश्चित गर्नुहोस् अनि आफ्नो <xliff:g id="PROFILE_NAME">%3$s</xliff:g> नजिकै राख्नुहोस्।"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"कुनै पनि डिभाइस भेटिएन। कृपया पछि फेरि प्रयास गर्नुहोस्।"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ब्लुटुथ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ब्लुटुथ तथा Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"घडी"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"आफूले <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> प्रयोग गरी व्यवस्थापन गर्न चाहेको डिभाइस चयन गर्नुहोस्"</string> <string name="chooser_title" msgid="2235819929238267637">"सेट अप गर्नका लागि <xliff:g id="PROFILE_NAME">%1$s</xliff:g> छनौट गर्नुहोस्"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> खोजिँदै छ"</string> <string name="summary_watch" msgid="8134580124808507407">"तपाईंको <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> मा यो एपलाई कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्ने र यी कुराहरू गर्ने अनुमति दिइने छ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> व्यवस्थापन गर्ने अनुमति दिने हो?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"डिभाइस"</string> diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml index 069c00c85cfc..5e389611eaa4 100644 --- a/packages/CompanionDeviceManager/res/values-nl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Toestaan dat de app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang heeft tot de <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Zorg dat <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> aanstaat op deze <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> en houd je <xliff:g id="PROFILE_NAME">%3$s</xliff:g> in de buurt."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Geen apparaten gevonden. Probeer het later opnieuw."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wifi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth en wifi"</string> <string name="profile_name_watch" msgid="576290739483672360">"smartwatch"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Een apparaat kiezen om te beheren met <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om in te stellen"</string> + <string name="single_device_title" msgid="4199861437545438606">"Zoeken naar een <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Deze app kan informatie synchroniseren (zoals de naam van iemand die belt) en krijgt toegang tot deze rechten op je <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toestaan <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> te beheren?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"apparaat"</string> diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml index a1a6c9023503..14dcc18a532d 100644 --- a/packages/CompanionDeviceManager/res/values-or/strings.xml +++ b/packages/CompanionDeviceManager/res/values-or/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ସହଯୋଗୀ ଡିଭାଇସ୍ ପରିଚାଳକ"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ଆପକୁ ଅନୁମତି ଦେବେ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ସୁନିଶ୍ଚିତ ହୁଏନ୍ତୁ ଏହି <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>ରେ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ଚାଲୁ କରାଯାଇଛି ଏବଂ ଆପଣଙ୍କର <xliff:g id="PROFILE_NAME">%3$s</xliff:g> ଆଖପାଖରେ ରଖନ୍ତୁ।"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"କୌଣସି ଡିଭାଇସ ମିଳିଲା ନାହିଁ। ଦୟାକରି ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ବ୍ଲୁଟୁଥ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"ୱାଇ-ଫାଇ"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ବ୍ଲୁଟୁଥ ଏବଂ ୱାଇ-ଫାଇ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ୱାଚ୍"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ ଡିଭାଇସ ବାଛନ୍ତୁ"</string> <string name="chooser_title" msgid="2235819929238267637">"ସେଟ ଅପ କରିବାକୁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ବାଛନ୍ତୁ"</string> + <string name="single_device_title" msgid="4199861437545438606">"ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ଖୋଜୁଛନ୍ତି"</string> <string name="summary_watch" msgid="8134580124808507407">"କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏବଂ ଆପଣଙ୍କ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>ରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦେବେ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ଡିଭାଇସ"</string> diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml index cd40ec7a5579..c2db62f88248 100644 --- a/packages/CompanionDeviceManager/res/values-pa/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ਸੰਬੰਧੀ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ"</string> <string name="confirmation_title" msgid="2244241995958340998">"ਕੀ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਐਪ ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ਪੱਕਾ ਕਰੋ ਕਿ ਇਸ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ਦਾ <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ਚਾਲੂ ਹੋਵੇ ਅਤੇ <xliff:g id="PROFILE_NAME">%3$s</xliff:g> ਨੂੰ ਆਪਣੇ ਨਜ਼ਦੀਕ ਰੱਖੋ।"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ਕੋਈ ਡੀਵਾਈਸ ਨਹੀਂ ਮਿਲਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"ਬਲੂਟੁੱਥ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"ਵਾਈ-ਫਾਈ"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"ਬਲੂਟੁੱਥ ਅਤੇ ਵਾਈ-ਫਾਈ"</string> <string name="profile_name_watch" msgid="576290739483672360">"ਸਮਾਰਟ-ਵਾਚ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ ਕੋਈ ਡੀਵਾਈਸ ਚੁਣੋ"</string> <string name="chooser_title" msgid="2235819929238267637">"ਸੈੱਟਅੱਪ ਕਰਨ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਨੂੰ ਲੱਭਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string> <string name="summary_watch" msgid="8134580124808507407">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> \'ਤੇ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰਨ ਅਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"ਕੀ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"ਡੀਵਾਈਸ"</string> diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml index b16776631dfc..90bc1e3bc34b 100644 --- a/packages/CompanionDeviceManager/res/values-pl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Menedżer urządzeń towarzyszących"</string> <string name="confirmation_title" msgid="2244241995958340998">"Zezwolić aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do urządzenia <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Upewnij się, że <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ma włączoną funkcję <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, i trzymaj urządzenie <xliff:g id="PROFILE_NAME">%3$s</xliff:g> w pobliżu."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nie znaleziono urządzeń. Spróbuj ponownie później."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth i Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"zegarek"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Wybierz urządzenie, którym ma zarządzać aplikacja <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, aby go skonfigurować"</string> + <string name="single_device_title" msgid="4199861437545438606">"Szukam: <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aplikacja będzie mogła synchronizować informacje takie jak nazwa dzwoniącego oraz korzystać z tych uprawnień na Twoim urządzeniu (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zezwolić na dostęp aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> do urządzenia <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"urządzenie"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml index a6c09d06f143..073fa260c401 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string> <string name="confirmation_title" msgid="2244241995958340998">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Confira se o <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> tem o <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ativado e se o <xliff:g id="PROFILE_NAME">%3$s</xliff:g> está por perto."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nenhum dispositivo foi encontrado. Tente de novo mais tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"Procurando um <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"O app poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões no seu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gerencie o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml index 01af6df4f89d..bec6f11edf51 100644 --- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gestor de dispositivos associados"</string> <string name="confirmation_title" msgid="2244241995958340998">"Permitir que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aceda ao <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Certifique-se de que este <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> tem o <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ativado e mantenha o <xliff:g id="PROFILE_NAME">%3$s</xliff:g> próximo."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nenhum dispositivo encontrado. Tente mais tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerido pela app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Escolha um perfil de <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"À procura de um <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Esta app vai poder sincronizar informações, como o nome do autor de uma chamada, e aceder a estas autorizações no seu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permita que a app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> faça a gestão do dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml index a6c09d06f143..073fa260c401 100644 --- a/packages/CompanionDeviceManager/res/values-pt/strings.xml +++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Gerenciador de dispositivos complementar"</string> <string name="confirmation_title" msgid="2244241995958340998">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Confira se o <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> tem o <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ativado e se o <xliff:g id="PROFILE_NAME">%3$s</xliff:g> está por perto."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nenhum dispositivo foi encontrado. Tente de novo mais tarde."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"relógio"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolha um dispositivo para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para configurar"</string> + <string name="single_device_title" msgid="4199861437545438606">"Procurando um <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"O app poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões no seu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gerencie o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispositivo"</string> diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml index 2b8b5e10b792..40ae72e6f10d 100644 --- a/packages/CompanionDeviceManager/res/values-ro/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Manager de dispozitiv Companion"</string> <string name="confirmation_title" msgid="2244241995958340998">"Permiți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze dispozitivul <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Asigură-te că dispozitivul <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> are activat <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> și ține <xliff:g id="PROFILE_NAME">%3$s</xliff:g> în apropiere."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nu s-au găsit dispozitive. Încearcă din nou mai târziu."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth și Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ceas"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Alege un dispozitiv pe care să îl gestioneze <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Alege un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> de configurat"</string> + <string name="single_device_title" msgid="4199861437545438606">"Se caută un <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, și să acceseze aceste permisiuni pe <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permiți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să gestioneze <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"dispozitiv"</string> diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml index 605fbd9bbc60..42acfb7a4d36 100644 --- a/packages/CompanionDeviceManager/res/values-ru/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Управление подключенными устройствами"</string> <string name="confirmation_title" msgid="2244241995958340998">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ к устройству <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Убедитесь, что <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> может устанавливать соединение с другими устройствами по <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> и что нужные настройки включены. Не убирайте <xliff:g id="PROFILE_NAME">%3$s</xliff:g> далеко от него."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Устройства не найдены. Повторите попытку позже."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth и Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"часы"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Выберите устройство, которым будет управлять приложение <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Выберите <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для настройки"</string> + <string name="single_device_title" msgid="4199861437545438606">"Поиск устройства (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>)"</string> <string name="summary_watch" msgid="8134580124808507407">"Это приложение сможет синхронизировать данные, например имена звонящих, и получит такие же разрешения на вашем устройстве (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)."</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> управлять устройством <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"устройстве"</string> diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml index 63024cac9c25..cc04f4b197c9 100644 --- a/packages/CompanionDeviceManager/res/values-si/strings.xml +++ b/packages/CompanionDeviceManager/res/values-si/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"සහායක උපාංග කළමනාකරු"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> යෙදුමට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> වෙත ප්රවේශ වීමට ඉඩ දෙන්න ද?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"මෙම <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ක්රියාත්මක කර ඇති බවට වග බලා ගන්න, සහ ඔබේ <xliff:g id="PROFILE_NAME">%3$s</xliff:g> ළඟ තබා ගන්න."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"උපාංග හමු නොවිණි. පසුව නැවත උත්සාහ කරන්න."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"බ්ලූටූත්"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"බ්ලූටූත් සහ Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ඔරලෝසුව"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> විසින් කළමනා කරනු ලැබීමට උපාංගයක් තෝරන්න"</string> <string name="chooser_title" msgid="2235819929238267637">"සැකසීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> සඳහා සොයමින්"</string> <string name="summary_watch" msgid="8134580124808507407">"මෙම යෙදුමට අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට, සහ ඔබේ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> මත මෙම අවසර වෙත ප්රවේශ වීමට ඉඩ දෙනු ඇත"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> කළමනා කිරීමට ඉඩ දෙන්න ද?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"උපාංගය"</string> diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml index f80ceca5ead9..9ee2ce574cc0 100644 --- a/packages/CompanionDeviceManager/res/values-sk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Správca sprievodných zariadení"</string> <string name="confirmation_title" msgid="2244241995958340998">"Chcete povoliť aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k zariadeniu <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Uistite sa, že tento typ zariadenia (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>) má zapnutú funkciu <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, a majte <xliff:g id="PROFILE_NAME">%3$s</xliff:g> nablízku."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nenašli sa žiadne zariadenia. Skúste to neskôr."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth a Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"hodinky"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Vyberte zariadenie, ktoré bude spravovať aplikácia <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý nastavíte"</string> + <string name="single_device_title" msgid="4199861437545438606">"Hľadá sa zariadenie <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, a získavať prístup k týmto povoleniam v zariadení <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Chcete povoliť aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> spravovať zariadenie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"zariadenie"</string> diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml index 2db2b7861003..3d08276d0e19 100644 --- a/packages/CompanionDeviceManager/res/values-sl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Upravitelj spremljevalnih naprav"</string> <string name="confirmation_title" msgid="2244241995958340998">"Želite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoliti dostop do naprave <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Poskrbite, da je v napravi <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> vklopljena nastavitev »<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>«, in napravo <xliff:g id="PROFILE_NAME">%3$s</xliff:g> imejte v bližini."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Ni naprav. Poskusite znova pozneje."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth in Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ura"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Izbira naprave, ki jo bo upravljala aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Izberite profil naprave »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>« za nastavitev"</string> + <string name="single_device_title" msgid="4199861437545438606">"Iskanje naprave <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, in dostopala do teh dovoljenj v napravi »<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>«."</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoliti upravljanje naprave <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"naprava"</string> diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml index 45f008db9594..de3232201da0 100644 --- a/packages/CompanionDeviceManager/res/values-sq/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Menaxheri i pajisjes shoqëruese"</string> <string name="confirmation_title" msgid="2244241995958340998">"T\'i lejohet aplikacionit <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> qasja te <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Sigurohu që ky <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> të ketë të aktivizuar<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> dhe mbaje <xliff:g id="PROFILE_NAME">%3$s</xliff:g> tënde pranë."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Nuk u gjet asnjë pajisje. Provo përsëri më vonë."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth-in"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth-in dhe Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"ora inteligjente"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Zgjidh një pajisje që do të menaxhohet nga <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Zgjidh një <xliff:g id="PROFILE_NAME">%1$s</xliff:g> për konfigurimin"</string> + <string name="single_device_title" msgid="4199861437545438606">"Po kërkon për një <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Këtij aplikacioni do t\'i lejohet të sinkronizojë informacione, si p.sh. emrin e dikujt që po telefonon, si dhe të ketë qasje në këto leje te <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Të lejohet që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të menaxhojë <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"pajisje"</string> diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml index 650d2d892e90..a86d1e1a5639 100644 --- a/packages/CompanionDeviceManager/res/values-sr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Менаџер придруженог уређаја"</string> <string name="confirmation_title" msgid="2244241995958340998">"Дозволите да апликација <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа уређају <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Уверите се да је за <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> укључен <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> и да у близини имате <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Није пронађен ниједан уређај. Пробајте поново касније."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WiFi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth и WiFi"</string> <string name="profile_name_watch" msgid="576290739483672360">"сат"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Одаберите уређај којим ће управљати апликација <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Одаберите профил <xliff:g id="PROFILE_NAME">%1$s</xliff:g> који желите да подесите"</string> + <string name="single_device_title" msgid="4199861437545438606">"Тражи се <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Овој апликацији ће бити дозвољено да синхронизује податке, попут имена позиваоца, и приступа тим дозволама на уређају <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Желите ли да дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> управља уређајем <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"уређај"</string> diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml index d28bff87b674..779079092f50 100644 --- a/packages/CompanionDeviceManager/res/values-sv/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vill du tillåta att appen <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> får åtkomst till <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Se till att <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> har <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> aktiverat och håll <xliff:g id="PROFILE_NAME">%3$s</xliff:g> i närheten."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Inga enheter hittades. Försök igen senare."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wifi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth och wifi"</string> <string name="profile_name_watch" msgid="576290739483672360">"klocka"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Välj en enhet för hantering av <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för konfigurering"</string> + <string name="single_device_title" msgid="4199861437545438606">"Söker efter ett <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Appen får synkronisera information, till exempel namnet på någon som ringer, och får åtkomst till dessa behörigheter på din <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Tillåt att <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hanterar <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"enhet"</string> diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml index afa3ea63b5bf..c0108372a318 100644 --- a/packages/CompanionDeviceManager/res/values-sw/strings.xml +++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Kidhibiti cha Vifaa Visaidizi"</string> <string name="confirmation_title" msgid="2244241995958340998">"Ungependa kuruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Hakikisha kuwa umewasha <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> kwenye <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> na uweke <xliff:g id="PROFILE_NAME">%3$s</xliff:g> karibu nawe."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Hakuna vifaa vilivyopatikana. Tafadhali jaribu tena baadaye."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth na Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"saa"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Chagua kifaa cha kudhibitiwa na <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili uweke mipangilio"</string> + <string name="single_device_title" msgid="4199861437545438606">"Inatafuta <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Programu hii itaruhusiwa kusawazisha maelezo, kama vile jina la mtu anayepiga simu na kufikia ruhusa hizi kwenye <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> yako"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Ungependa kuruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> idhibiti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"kifaa"</string> diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml index fd2038a07dd6..96f7d6310a07 100644 --- a/packages/CompanionDeviceManager/res/values-ta/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> சாதனத்தை அணுக <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவா?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"இந்த <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> சாதனத்தின் <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ஆன் செய்யப்பட்டு, அதன் அருகில் உங்கள் <xliff:g id="PROFILE_NAME">%3$s</xliff:g> இருப்பதை உறுதிசெய்துகொள்ளவும்."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"சாதனங்கள் எதுவும் கண்டறியப்படவில்லை. பிறகு முயலவும்."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"புளூடூத்"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"வைஃபை"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"புளூடூத் மற்றும் வைஃபை"</string> <string name="profile_name_watch" msgid="576290739483672360">"வாட்ச்"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸால் நிர்வகிக்கப்பட வேண்டிய சாதனத்தைத் தேர்வுசெய்யுங்கள்"</string> <string name="chooser_title" msgid="2235819929238267637">"அமைக்க <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேர்வுசெய்யவும்"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ஐத் தேடுகிறது"</string> <string name="summary_watch" msgid="8134580124808507407">"அழைப்பவரின் பெயர் போன்ற தகவல்களை ஒத்திசைக்கவும் உங்கள் <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> சாதனத்தில் இந்த அனுமதிகளை அணுகவும் இந்த ஆப்ஸ் அனுமதிக்கப்படும்"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong&gt சாதனத்தை நிர்வகிக்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவா?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"சாதனம்"</string> diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml index 8466921f3634..b39b58a39df7 100644 --- a/packages/CompanionDeviceManager/res/values-te/strings.xml +++ b/packages/CompanionDeviceManager/res/values-te/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"సహచర పరికర మేనేజర్"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ను యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించాలా?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ఈ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>లో <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ఆన్లో ఉందని నిర్ధారించుకోండి, అలాగే మీ <xliff:g id="PROFILE_NAME">%3$s</xliff:g>ను దగ్గరగా ఉంచుకోండి."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"పరికరాలు ఏవీ కనుగొనబడలేదు. దయచేసి తర్వాత మళ్లీ ట్రై చేయండి."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"బ్లూటూత్"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"బ్లూటూత్, Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"వాచ్"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ద్వారా మేనేజ్ చేయబడే పరికరాన్ని ఎంచుకోండి"</string> <string name="chooser_title" msgid="2235819929238267637">"సెటప్ చేయడానికి <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> కోసం స్కాన్ చేస్తోంది"</string> <string name="summary_watch" msgid="8134580124808507407">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని సింక్ చేయడానికి, మీ <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ను మేనేజ్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించాలా?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"పరికరం"</string> diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml index 2e7ba3c6a37a..6a38c999ee4b 100644 --- a/packages/CompanionDeviceManager/res/values-th/strings.xml +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"อนุญาตให้แอป <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึง <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ใช่ไหม"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"ตรวจสอบว่า<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>เครื่องนี้เปิด<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>อยู่ และให้อยู่ใกล้กับ<xliff:g id="PROFILE_NAME">%3$s</xliff:g>"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"ไม่พบอุปกรณ์ โปรดลองอีกครั้งในภายหลัง"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"บลูทูธ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"บลูทูธและ Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"นาฬิกา"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"เลือกอุปกรณ์ที่จะให้มีการจัดการโดย <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะตั้งค่า"</string> + <string name="single_device_title" msgid="4199861437545438606">"กำลังค้นหา<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"แอปนี้จะได้รับอนุญาตให้ซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา และมีสิทธิ์เข้าถึงข้อมูลเหล่านี้ใน<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>ของคุณ"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> จัดการ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ไหม"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"อุปกรณ์"</string> diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml index 3f4e2af77df9..9150a48fafdd 100644 --- a/packages/CompanionDeviceManager/res/values-tl/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Kasamang Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"Payagan ang app na <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Siguraduhing naka-on ang <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> sa <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> na ito, at panatilihing nasa malapit ang iyong <xliff:g id="PROFILE_NAME">%3$s</xliff:g>."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Walang nakitang device. Pakisubukan ulit sa ibang pagkakataon."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth at Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"relo"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Pumili ng device na papamahalaan ng <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para mag-set up"</string> + <string name="single_device_title" msgid="4199861437545438606">"Hinahanap ang <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Papayagan ang app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, at ma-access ang mga pahintulot na ito sa iyong <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na pamahalaan ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"device"</string> diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml index 3e4603bea751..8ba76bc40653 100644 --- a/packages/CompanionDeviceManager/res/values-tr/strings.xml +++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazına erişmesi için <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasına izin verin"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Bu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> cihazında <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> özelliğinin etkinleştirildiğinden emin olun ve <xliff:g id="PROFILE_NAME">%3$s</xliff:g> cihazınızı yakında tutun."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Cihaz bulunamadı. Lütfen daha sonra tekrar deneyin."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Kablosuz"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth ve Kablosuz"</string> <string name="profile_name_watch" msgid="576290739483672360">"saat"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tarafından yönetilecek bir cihaz seçin"</string> <string name="chooser_title" msgid="2235819929238267637">"Ayarlamak için bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> aranıyor"</string> <string name="summary_watch" msgid="8134580124808507407">"Bu uygulamanın arayan kişinin adı gibi bilgileri senkronize etmesine ve <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> cihazınızda aşağıdaki izinlere erişmesine izin verilir"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasına <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazını yönetmesi için izin verilsin mi?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"Cihaz"</string> diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml index 18adf00c8c5b..ff93a657455d 100644 --- a/packages/CompanionDeviceManager/res/values-uk/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Диспетчер супутніх пристроїв"</string> <string name="confirmation_title" msgid="2244241995958340998">"Дозволити додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до інформації на пристрої <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Перевірте цей <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> і переконайтеся, що на ньому ввімкнено <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, а тоді тримайте <xliff:g id="PROFILE_NAME">%3$s</xliff:g> поблизу."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Пристрої не знайдено. Повторіть спробу пізніше."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth і Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"годинник"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Виберіть пристрій, яким керуватиме додаток <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g> для налаштування"</string> + <string name="single_device_title" msgid="4199861437545438606">"Шукаємо <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) і отримає доступ до перелічених нижче дозволів на вашому <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Дозволити додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> керувати пристроєм <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"пристрій"</string> diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml index cb1a5278dfc1..e502a792d23b 100644 --- a/packages/CompanionDeviceManager/res/values-ur/strings.xml +++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"ساتھی آلہ مینیجر"</string> <string name="confirmation_title" msgid="2244241995958340998">"ایپ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> تک رسائی کی اجازت دیں؟"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"یقینی بنائیں کہ اس <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> کا <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> آن ہے اور اپنی <xliff:g id="PROFILE_NAME">%3$s</xliff:g> کو قریب رکھیں۔"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"کوئی آلہ نہیں ملا۔ براہ کرم بعد میں دوبارہ کوشش کریں۔"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"بلوٹوتھ"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"بلوٹوتھ اور Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"دیکھیں"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کے ذریعے منتخب کیے جانے کیلئے آلہ منتخب کریں"</string> <string name="chooser_title" msgid="2235819929238267637">"سیٹ اپ کرنے کے لیے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کا انتخاب کریں"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو تلاش کیا جا رہا ہے"</string> <string name="summary_watch" msgid="8134580124808507407">"اس ایپ کو آپ کے <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> پر کسی کال کرنے والے کے نام جیسی معلومات کی مطابقت پذیری کرنے اور ان اجازتوں تک رسائی کی اجازت ہوگی"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کا نظم کرنے کی اجازت دیں؟"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"آلہ"</string> diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml index 993c50226103..076bb74d6bf6 100644 --- a/packages/CompanionDeviceManager/res/values-uz/strings.xml +++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Companion Device Manager"</string> <string name="confirmation_title" msgid="2244241995958340998">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qurilmasidan foydalanishga ruxsat berilsinmi?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Bu <xliff:g id="DEVICE_TYPE">%1$s</xliff:g>da <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> yoqilganini tekshiring va <xliff:g id="PROFILE_NAME">%3$s</xliff:g>ni tayyor tuting."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Hech qanday qurilma topilmadi. Keyinroq qayta urining."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth va Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"soat"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> boshqaradigan qurilmani tanlang"</string> <string name="chooser_title" msgid="2235819929238267637">"Sozlash uchun <xliff:g id="PROFILE_NAME">%1$s</xliff:g> profilini tanlang"</string> + <string name="single_device_title" msgid="4199861437545438606">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> qidirilmoqda"</string> <string name="summary_watch" msgid="8134580124808507407">"Bu ilovaga chaqiruvchining ismi kabi maʼlumotlarni sinxronlash va <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> qurilmasida quyidagi amallarni bajarishga ruxsat beriladi"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qurilmasini boshqarish uchun ruxsat berilsinmi?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"qurilma"</string> diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml index dee65de16b73..a44af74b1182 100644 --- a/packages/CompanionDeviceManager/res/values-vi/strings.xml +++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Trình quản lý thiết bị đồng hành"</string> <string name="confirmation_title" msgid="2244241995958340998">"Cho phép ứng dụng <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Hãy đảm bảo rằng <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> này đã bật <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> và được đặt gần <xliff:g id="PROFILE_NAME">%3$s</xliff:g> của bạn."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Không tìm thấy thiết bị nào. Vui lòng thử lại sau."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth và Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"đồng hồ"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Chọn một thiết bị sẽ do <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> quản lý"</string> <string name="chooser_title" msgid="2235819929238267637">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> để thiết lập"</string> + <string name="single_device_title" msgid="4199861437545438606">"Đang tìm <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Ứng dụng này sẽ được phép đồng bộ hoá thông tin (chẳng hạn như tên của người đang gọi điện) và dùng những quyền sau trên <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> của bạn"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> quản lý <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"thiết bị"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml index 605cab7185d8..4360092564ea 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"配套设备管理器"</string> <string name="confirmation_title" msgid="2244241995958340998">"允许应用<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>访问<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"请确保此<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>已开启<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>,并将<xliff:g id="PROFILE_NAME">%3$s</xliff:g>放在附近。"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"找不到设备,请稍后重试。"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"蓝牙"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"WLAN"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"蓝牙和 WLAN"</string> <string name="profile_name_watch" msgid="576290739483672360">"手表"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"选择要由<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>管理的设备"</string> <string name="chooser_title" msgid="2235819929238267637">"选择 <xliff:g id="PROFILE_NAME">%1$s</xliff:g> 进行设置"</string> + <string name="single_device_title" msgid="4199861437545438606">"寻找<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"该应用将能同步信息(例如来电者的姓名),并能获得您<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>上的以下权限"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"允许<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>管理<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"设备"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml index d1c73e538981..3dcaa9f7e5d6 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string> <string name="confirmation_title" msgid="2244241995958340998">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」應用程式<strong></strong>存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"請確保你已開啟此<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>的<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>,並將<xliff:g id="PROFILE_NAME">%3$s</xliff:g>放在附近。"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"找不到任何裝置,請稍後再試。"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"藍牙"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"藍牙和 Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"選擇要讓 <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> 管理的裝置"</string> <string name="chooser_title" msgid="2235819929238267637">"選擇要設定的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> + <string name="single_device_title" msgid="4199861437545438606">"正在搜尋<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"此應用程式將可同步資訊 (例如來電者的名稱),並可在<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>上取得以下權限"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string> diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml index c675fedb1dbd..2bfcaf296420 100644 --- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"隨附裝置管理工具"</string> <string name="confirmation_title" msgid="2244241995958340998">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>應用程式存取「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"請確認這個<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>已開啟<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>,並將<xliff:g id="PROFILE_NAME">%3$s</xliff:g>放在附近。"</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"找不到裝置,請稍後再試。"</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"藍牙"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"藍牙和 Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"手錶"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"選擇要讓「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理的裝置"</string> <string name="chooser_title" msgid="2235819929238267637">"選擇要設定的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> + <string name="single_device_title" msgid="4199861437545438606">"尋找<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"這個應用程式將可同步處理資訊 (例如來電者名稱) 及取得<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>上的這些權限"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"裝置"</string> diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml index 365b2f4753d0..bc7bb819b1c1 100644 --- a/packages/CompanionDeviceManager/res/values-zu/strings.xml +++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml @@ -18,9 +18,15 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="4470785958457506021">"Isiphathi sedivayisi esihambisanayo"</string> <string name="confirmation_title" msgid="2244241995958340998">"Vumela i-app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukufinyelela <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string> + <string name="message_discovery_soft_timeout" msgid="473346859407859161">"Qinisekisa ukuthi le-<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> ivule i-<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g>, futhi ugcine i-<xliff:g id="PROFILE_NAME">%3$s</xliff:g> yakho iseduze."</string> + <string name="message_discovery_hard_timeout" msgid="677514663495711424">"Awekho amadivayisi atholiwe. Sicela uzame futhi kamuva."</string> + <string name="discovery_bluetooth" msgid="5693557668470016164">"IBluetooth"</string> + <string name="discovery_wifi" msgid="1551782459721758773">"I-Wi-Fi"</string> + <string name="discovery_mixed" msgid="7071466134150760127">"IBluetooth ne-Wi-Fi"</string> <string name="profile_name_watch" msgid="576290739483672360">"buka"</string> <string name="chooser_title_non_profile" msgid="6035023914517087400">"Khetha idivayisi engaphathwa nge-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>"</string> <string name="chooser_title" msgid="2235819929238267637">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ukusetha"</string> + <string name="single_device_title" msgid="4199861437545438606">"Ufuna i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string> <string name="summary_watch" msgid="8134580124808507407">"Le app izovunyelwa ukuvumelanisa ulwazi, olufana negama lomuntu ofonayo, iphinde ifinyelele lezi zimvume ku-<xliff:g id="DEVICE_TYPE">%1$s</xliff:g> yakho"</string> <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukuthi ifinyelele i-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string> <string name="profile_name_glasses" msgid="3506504967216601277">"idivayisi"</string> diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml index 66ad31b3927c..0ef3a8fe9ffc 100644 --- a/packages/CredentialManager/res/values-eu/strings.xml +++ b/packages/CredentialManager/res/values-eu/strings.xml @@ -72,7 +72,7 @@ <string name="get_dialog_title_use_password_for" msgid="688557784207167647">"Erabili <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako pasahitza"</string> <string name="get_dialog_title_use_sign_in_for" msgid="4233553937542583226">"Erabili zure kontua <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako"</string> <string name="get_dialog_description_single_tap" msgid="2797059565126030879">"Erabili pantailaren blokeoa <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan <xliff:g id="USERNAME">%2$s</xliff:g> kontuarekin saioa hasteko"</string> - <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Desblokeatu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko aukerak"</string> + <string name="get_dialog_title_unlock_options_for" msgid="7096423827682163270">"Desblokeatu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko moduak"</string> <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako sarbide-gakoa"</string> <string name="get_dialog_title_choose_password_for" msgid="1724435823820819221">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako pasahitza"</string> <string name="get_dialog_title_choose_saved_sign_in_for" msgid="2420298653461652728">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako saioa hasteko moduak"</string> @@ -82,7 +82,7 @@ <string name="get_dialog_use_saved_passkey_for" msgid="4618100798664888512">"Hasi saioa beste modu batean"</string> <string name="snackbar_action" msgid="37373514216505085">"Ikusi aukerak"</string> <string name="get_dialog_button_label_continue" msgid="6446201694794283870">"Egin aurrera"</string> - <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Saioa hasteko aukerak"</string> + <string name="get_dialog_title_sign_in_options" msgid="2092876443114893618">"Saioa hasteko moduak"</string> <string name="button_label_view_more" msgid="3429098227286495651">"Ikusi gehiago"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearenak"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"Blokeatutako pasahitz-kudeatzaileak"</string> diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml index 51f163922203..7f944b4c3310 100644 --- a/packages/CredentialManager/res/values-iw/strings.xml +++ b/packages/CredentialManager/res/values-iw/strings.xml @@ -86,7 +86,7 @@ <string name="button_label_view_more" msgid="3429098227286495651">"עוד מידע"</string> <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"עבור <xliff:g id="USERNAME">%1$s</xliff:g>"</string> <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"מנהלי סיסמאות נעולים"</string> - <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"יש להקיש כדי לבטל את הנעילה"</string> + <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"יש ללחוץ כדי לבטל את הנעילה"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"אין פרטי כניסה"</string> <string name="no_sign_in_info_in" msgid="2641118151920288356">"אין פרטי כניסה ב-<xliff:g id="SOURCE">%1$s</xliff:g>"</string> <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"ניהול כניסות"</string> diff --git a/packages/CredentialManager/wear/res/values-iw/strings.xml b/packages/CredentialManager/wear/res/values-iw/strings.xml index 4fb203d43386..bc9e180e79fe 100644 --- a/packages/CredentialManager/wear/res/values-iw/strings.xml +++ b/packages/CredentialManager/wear/res/values-iw/strings.xml @@ -30,5 +30,5 @@ <string name="choose_password_title" msgid="7610721820858017214">"בחירת סיסמה"</string> <string name="sign_in_on_phone_button" msgid="7618621977586522403">"כניסה לחשבון בטלפון"</string> <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"אין פרטי כניסה"</string> - <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"צריך להקיש כדי לבטל את הנעילה"</string> + <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"צריך ללחוץ כדי לבטל את הנעילה"</string> </resources> diff --git a/packages/InputDevices/res/values-af/strings.xml b/packages/InputDevices/res/values-af/strings.xml index cd9d915d87fd..e364576c4001 100644 --- a/packages/InputDevices/res/values-af/strings.xml +++ b/packages/InputDevices/res/values-af/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegryns (Latyns)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serwies (Cyrillies)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegryns (Cyrillies)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roemeens"</string> </resources> diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml index a6f5f3a7018f..db5a7d404a58 100644 --- a/packages/InputDevices/res/values-am/strings.xml +++ b/packages/InputDevices/res/values-am/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ሞንቴኔግሮኛ (ላቲን)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ሰርቢያኛ (ሲሪሊክኛ)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ሞንቴኔግሮኛ (ሲሪሊክኛ)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ሮማኒያኛ"</string> </resources> diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml index f92d0def3b7e..65f3edb2604c 100644 --- a/packages/InputDevices/res/values-ar/strings.xml +++ b/packages/InputDevices/res/values-ar/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"لغة الجبل الأسود (اللاتينية)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"الصربية (السيريلية)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"لغة الجبل الأسود (السيريلية)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-as/strings.xml b/packages/InputDevices/res/values-as/strings.xml index 8084da395175..c4eaafb195c9 100644 --- a/packages/InputDevices/res/values-as/strings.xml +++ b/packages/InputDevices/res/values-as/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"মণ্টেনেগ্ৰিণ (লেটিন)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ছাৰ্বিয়ান (চিৰিলিক)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মণ্টেনেগ্ৰিণ (চিৰিলিক)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ৰোমানিয়ান"</string> </resources> diff --git a/packages/InputDevices/res/values-az/strings.xml b/packages/InputDevices/res/values-az/strings.xml index 068a771d9c50..d71c3960601d 100644 --- a/packages/InputDevices/res/values-az/strings.xml +++ b/packages/InputDevices/res/values-az/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monteneqro dili (Latın)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb dili (Kiril)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monteneqro dili (Kiril)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumın dili"</string> </resources> diff --git a/packages/InputDevices/res/values-b+sr+Latn/strings.xml b/packages/InputDevices/res/values-b+sr+Latn/strings.xml index 334b03218f91..e670ed4f843c 100644 --- a/packages/InputDevices/res/values-b+sr+Latn/strings.xml +++ b/packages/InputDevices/res/values-b+sr+Latn/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunski"</string> </resources> diff --git a/packages/InputDevices/res/values-be/strings.xml b/packages/InputDevices/res/values-be/strings.xml index c11266512978..c8c04d400eb8 100644 --- a/packages/InputDevices/res/values-be/strings.xml +++ b/packages/InputDevices/res/values-be/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Чарнагорская (лацініца)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербская (кірыліца)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чарнагорская (кірыліца)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынская"</string> </resources> diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml index 8a650b283f4f..82c39657b003 100644 --- a/packages/InputDevices/res/values-bg/strings.xml +++ b/packages/InputDevices/res/values-bg/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"черногорски (латиница)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"сръбски (кирилица)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"черногорски (кирилица)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"румънски"</string> </resources> diff --git a/packages/InputDevices/res/values-bn/strings.xml b/packages/InputDevices/res/values-bn/strings.xml index 02ab5075b991..de54cdf688c4 100644 --- a/packages/InputDevices/res/values-bn/strings.xml +++ b/packages/InputDevices/res/values-bn/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"মন্টেনেগ্রিন (ল্যাটিন)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"সার্বিয়ান (সিরিলিক)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"মন্টেনেগ্রিন (সিরিলিক)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"রোমানিয়ান"</string> </resources> diff --git a/packages/InputDevices/res/values-bs/strings.xml b/packages/InputDevices/res/values-bs/strings.xml index e1aef5d67d89..9b7b33112643 100644 --- a/packages/InputDevices/res/values-bs/strings.xml +++ b/packages/InputDevices/res/values-bs/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunski"</string> </resources> diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml index f9b2e5eb342a..874e06bb69cf 100644 --- a/packages/InputDevices/res/values-ca/strings.xml +++ b/packages/InputDevices/res/values-ca/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrí (llatí)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbi (ciríl·lic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrí (ciríl·lic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanès"</string> </resources> diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml index 72efbc4cc999..6a46b1473089 100644 --- a/packages/InputDevices/res/values-cs/strings.xml +++ b/packages/InputDevices/res/values-cs/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"černohorština (latinka)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbština (cyrilice)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"černohorština (cyrilice)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml index 6ce0b8b9febe..246baba5be18 100644 --- a/packages/InputDevices/res/values-da/strings.xml +++ b/packages/InputDevices/res/values-da/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrinsk (latinsk)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinsk (kyrillisk)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumænsk"</string> </resources> diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml index 0dc4e2a0aa49..21a939a3d007 100644 --- a/packages/InputDevices/res/values-de/strings.xml +++ b/packages/InputDevices/res/values-de/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrinisch (lat. Alphabet)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisch (kyrillisch)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrinisch (kyrillisch)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumänisch"</string> </resources> diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml index 08357db6b06b..eabb90c86daf 100644 --- a/packages/InputDevices/res/values-el/strings.xml +++ b/packages/InputDevices/res/values-el/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Μαυροβουνιακά (Λατινικά)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Σερβικά (Κυριλλικά)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Μαυροβουνιακά (Κυριλλικά)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Ρουμανικά"</string> </resources> diff --git a/packages/InputDevices/res/values-en-rAU/strings.xml b/packages/InputDevices/res/values-en-rAU/strings.xml index 0e9e6ebb7f38..7b72cba5c863 100644 --- a/packages/InputDevices/res/values-en-rAU/strings.xml +++ b/packages/InputDevices/res/values-en-rAU/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string> </resources> diff --git a/packages/InputDevices/res/values-en-rCA/strings.xml b/packages/InputDevices/res/values-en-rCA/strings.xml index 3fa4bce3dfc3..d78dce2ff927 100644 --- a/packages/InputDevices/res/values-en-rCA/strings.xml +++ b/packages/InputDevices/res/values-en-rCA/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string> </resources> diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml index 0e9e6ebb7f38..7b72cba5c863 100644 --- a/packages/InputDevices/res/values-en-rGB/strings.xml +++ b/packages/InputDevices/res/values-en-rGB/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string> </resources> diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml index 0e9e6ebb7f38..7b72cba5c863 100644 --- a/packages/InputDevices/res/values-en-rIN/strings.xml +++ b/packages/InputDevices/res/values-en-rIN/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string> </resources> diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml index 321b9a595dfa..2a4035ad5eed 100644 --- a/packages/InputDevices/res/values-es-rUS/strings.xml +++ b/packages/InputDevices/res/values-es-rUS/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumano"</string> </resources> diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml index 98076524b5e8..ba1ef20e24b6 100644 --- a/packages/InputDevices/res/values-es/strings.xml +++ b/packages/InputDevices/res/values-es/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumano"</string> </resources> diff --git a/packages/InputDevices/res/values-et/strings.xml b/packages/InputDevices/res/values-et/strings.xml index eb7ea9fd2843..99f36260cc41 100644 --- a/packages/InputDevices/res/values-et/strings.xml +++ b/packages/InputDevices/res/values-et/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegro (ladina)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kirillitsa)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kirillitsa)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumeenia"</string> </resources> diff --git a/packages/InputDevices/res/values-eu/strings.xml b/packages/InputDevices/res/values-eu/strings.xml index 53707598b264..9fae4f99b09d 100644 --- a/packages/InputDevices/res/values-eu/strings.xml +++ b/packages/InputDevices/res/values-eu/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegroarra (latindarra)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbiarra (zirilikoa)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegroarra (zirilikoa)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Errumaniera"</string> </resources> diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml index 9bbf4e36fa16..cbc6b65148b9 100644 --- a/packages/InputDevices/res/values-fa/strings.xml +++ b/packages/InputDevices/res/values-fa/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"مونتهنگرویی (لاتین)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"صربی (سیریلیک)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونتهنگرویی (سیریلیک)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"رومانیایی"</string> </resources> diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml index 3e88c2085373..736d7cbd77c3 100644 --- a/packages/InputDevices/res/values-fi/strings.xml +++ b/packages/InputDevices/res/values-fi/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegro (latinalainen)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbia (kyrillinen)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegro (kyrillinen)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"romania"</string> </resources> diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml index 690fbad6ab12..7b99d3bc33bc 100644 --- a/packages/InputDevices/res/values-fr-rCA/strings.xml +++ b/packages/InputDevices/res/values-fr-rCA/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monténégrin (latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roumain"</string> </resources> diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml index 70bd250738f7..8628f8f7c0eb 100644 --- a/packages/InputDevices/res/values-fr/strings.xml +++ b/packages/InputDevices/res/values-fr/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Monténégrin (latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbe (cyrillique)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Monténégrin (cyrillique)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roumain"</string> </resources> diff --git a/packages/InputDevices/res/values-gl/strings.xml b/packages/InputDevices/res/values-gl/strings.xml index 058dba52e17b..5e681e6032dc 100644 --- a/packages/InputDevices/res/values-gl/strings.xml +++ b/packages/InputDevices/res/values-gl/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (alfabeto latino)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanés"</string> </resources> diff --git a/packages/InputDevices/res/values-gu/strings.xml b/packages/InputDevices/res/values-gu/strings.xml index 3f1b31a8a6c8..a5a522ecbf31 100644 --- a/packages/InputDevices/res/values-gu/strings.xml +++ b/packages/InputDevices/res/values-gu/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"મોંટેનેગ્રીન (લેટિન)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"સર્બિયન (સિરિલિક)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"મોંટેનેગ્રીન (સિરિલિક)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"રોમાનિયન"</string> </resources> diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml index db59ebac7805..ad9c980d00a9 100644 --- a/packages/InputDevices/res/values-hi/strings.xml +++ b/packages/InputDevices/res/values-hi/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मॉन्टेनीग्रिन (लैटिन)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोंटेनेग्रिन (सिरिलिक)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमेनियन"</string> </resources> diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml index 905dce25b4aa..b7e8ee4cad17 100644 --- a/packages/InputDevices/res/values-hr/strings.xml +++ b/packages/InputDevices/res/values-hr/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"crnogorski (latinica)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srpski (ćirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"crnogorski (ćirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunjski"</string> </resources> diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml index 4c8e7b8de6ba..756cc0846ff2 100644 --- a/packages/InputDevices/res/values-hu/strings.xml +++ b/packages/InputDevices/res/values-hu/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegrói (latin betűs)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"szerb (cirill betűs)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrói (cirill betűs)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"román"</string> </resources> diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml index ae56fc5b1620..eced5cdbde2d 100644 --- a/packages/InputDevices/res/values-hy/strings.xml +++ b/packages/InputDevices/res/values-hy/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"չեռնոգորերեն (լատինատառ)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"սերբերեն (կյուրեղատառ)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"չեռնոգորերեն (կյուրեղատառ)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Ռումիներեն"</string> </resources> diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml index 52bc03943abd..e871d1947fab 100644 --- a/packages/InputDevices/res/values-in/strings.xml +++ b/packages/InputDevices/res/values-in/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegro (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Sirilik)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegro (Sirilik)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumania"</string> </resources> diff --git a/packages/InputDevices/res/values-is/strings.xml b/packages/InputDevices/res/values-is/strings.xml index 0f516cef370e..ec5d98b24ec6 100644 --- a/packages/InputDevices/res/values-is/strings.xml +++ b/packages/InputDevices/res/values-is/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Svartfellska (latneskt)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbneska (kyrillískt)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Svartfellska (kyrillískt)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rúmenska"</string> </resources> diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml index f77b87cc67be..06ceb7affeeb 100644 --- a/packages/InputDevices/res/values-it/strings.xml +++ b/packages/InputDevices/res/values-it/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latino)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbo (cirillico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirillico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumeno"</string> </resources> diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml index 0e400e2d0fa4..4cf8098fded7 100644 --- a/packages/InputDevices/res/values-iw/strings.xml +++ b/packages/InputDevices/res/values-iw/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"מונטנגרית (לטינית)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"סרבית (אותיות קיריליות)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"מונטנגרית (אותיות קיריליות)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml index b1830ebda199..4c6de705565e 100644 --- a/packages/InputDevices/res/values-ja/strings.xml +++ b/packages/InputDevices/res/values-ja/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"モンテネグロ語(ラテン)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"セルビア語(キリル)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"モンテネグロ語(キリル)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ルーマニア語"</string> </resources> diff --git a/packages/InputDevices/res/values-ka/strings.xml b/packages/InputDevices/res/values-ka/strings.xml index 75c72b91df94..7232c1a7db9c 100644 --- a/packages/InputDevices/res/values-ka/strings.xml +++ b/packages/InputDevices/res/values-ka/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"მონტენეგრული (ლათინური)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"სერბული (კირილიცა)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"მონტენეგრული (კირილიცა)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"რუმინული"</string> </resources> diff --git a/packages/InputDevices/res/values-kk/strings.xml b/packages/InputDevices/res/values-kk/strings.xml index c0a58685bc52..278c868d76d4 100644 --- a/packages/InputDevices/res/values-kk/strings.xml +++ b/packages/InputDevices/res/values-kk/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Черногор (латын жазуы)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербия (кириллица)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногория (кириллица)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румын"</string> </resources> diff --git a/packages/InputDevices/res/values-km/strings.xml b/packages/InputDevices/res/values-km/strings.xml index 6c3db64fa1e9..2eaeaa7f03ac 100644 --- a/packages/InputDevices/res/values-km/strings.xml +++ b/packages/InputDevices/res/values-km/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ម៉ុងតេណេហ្គ្រោ (ឡាតាំង)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"សែប៊ី (ស៊ីរីលីក)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ម៉ុងតេណេហ្គ្រោ (ស៊ីរីលីក)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"រ៉ូម៉ានី"</string> </resources> diff --git a/packages/InputDevices/res/values-kn/strings.xml b/packages/InputDevices/res/values-kn/strings.xml index 0f4c5229c4d4..8039039ca0fc 100644 --- a/packages/InputDevices/res/values-kn/strings.xml +++ b/packages/InputDevices/res/values-kn/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ಮೊಂಟೆನೆಗ್ರಿನ್ (ಲ್ಯಾಟಿನ್)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ಸೆರ್ಬಿಯನ್ (ಸಿರಿಲಿಕ್)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ಮೊಂಟೆನೆಗ್ರಿನ್ (ಸಿರಿಲಿಕ್)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ರೊಮೇನಿಯನ್"</string> </resources> diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml index dcfb3b4ece40..de1bb3d5dbe6 100644 --- a/packages/InputDevices/res/values-ko/strings.xml +++ b/packages/InputDevices/res/values-ko/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"몬테네그로어(로마자)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"세르비아어(키릴 자모)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"몬테네그로어(키릴)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"루마니아어"</string> </resources> diff --git a/packages/InputDevices/res/values-ky/strings.xml b/packages/InputDevices/res/values-ky/strings.xml index c0b3d3a1d9b3..47bf7b73405f 100644 --- a/packages/InputDevices/res/values-ky/strings.xml +++ b/packages/InputDevices/res/values-ky/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Монтенегрочо (Латын)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербче (Кирилл)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногориялыкча (Кирилл)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынча"</string> </resources> diff --git a/packages/InputDevices/res/values-lo/strings.xml b/packages/InputDevices/res/values-lo/strings.xml index c2e5a2beded5..6a35f23b4f9e 100644 --- a/packages/InputDevices/res/values-lo/strings.xml +++ b/packages/InputDevices/res/values-lo/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ມອນເທເນກຣິນ (ລາຕິນ)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ເຊີບຽນ (ຊີຣິວລິກ)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ມອນເທເນກຣິນ (ຊີຣິວລິກ)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ໂຣມານຽນ"</string> </resources> diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml index 9a98e8eb5b13..4bf9223099d1 100644 --- a/packages/InputDevices/res/values-lt/strings.xml +++ b/packages/InputDevices/res/values-lt/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Juodkalniečių (lotynų rašmenys)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbų (kirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Juodkalniečių (kirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumunų"</string> </resources> diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml index d3422b210757..90d690ca10b7 100644 --- a/packages/InputDevices/res/values-lv/strings.xml +++ b/packages/InputDevices/res/values-lv/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Melnkalniešu (latīņu)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbu (kirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Melnkalniešu (kirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumāņu"</string> </resources> diff --git a/packages/InputDevices/res/values-mk/strings.xml b/packages/InputDevices/res/values-mk/strings.xml index ccb09392aed3..4c80a80af8a3 100644 --- a/packages/InputDevices/res/values-mk/strings.xml +++ b/packages/InputDevices/res/values-mk/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"црногорски (латиница)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (кирилица)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (кирилица)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"романски"</string> </resources> diff --git a/packages/InputDevices/res/values-ml/strings.xml b/packages/InputDevices/res/values-ml/strings.xml index 5a7b601baa97..41ea10f22aa3 100644 --- a/packages/InputDevices/res/values-ml/strings.xml +++ b/packages/InputDevices/res/values-ml/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"മോണ്ടിനെഗ്രിൻ (ലാറ്റിൻ)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"സെർബിയൻ (സിറിലിക്)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"മോണ്ടിനെഗ്രിൻ (സിറിലിക്)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"റൊമേനിയൻ"</string> </resources> diff --git a/packages/InputDevices/res/values-mn/strings.xml b/packages/InputDevices/res/values-mn/strings.xml index 0044eb24bc6a..056e728f4687 100644 --- a/packages/InputDevices/res/values-mn/strings.xml +++ b/packages/InputDevices/res/values-mn/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Монтенегро (латин)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Серби (кирилл)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Монтенегро (кирилл)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румын"</string> </resources> diff --git a/packages/InputDevices/res/values-mr/strings.xml b/packages/InputDevices/res/values-mr/strings.xml index d306dda71553..fe032fe3999e 100644 --- a/packages/InputDevices/res/values-mr/strings.xml +++ b/packages/InputDevices/res/values-mr/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मॉन्टेनेग्रिन (लॅटिन)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियन (सिरिलिक)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मॉन्टेनेग्रिन (सिरिलिक)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमानियन"</string> </resources> diff --git a/packages/InputDevices/res/values-ms/strings.xml b/packages/InputDevices/res/values-ms/strings.xml index d1b16547f8e6..f9d18a1055ef 100644 --- a/packages/InputDevices/res/values-ms/strings.xml +++ b/packages/InputDevices/res/values-ms/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbia (Cyril)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyril)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Bahasa Romania"</string> </resources> diff --git a/packages/InputDevices/res/values-my/strings.xml b/packages/InputDevices/res/values-my/strings.xml index fb553446dbd4..47498e079981 100644 --- a/packages/InputDevices/res/values-my/strings.xml +++ b/packages/InputDevices/res/values-my/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"မွန်တီနီဂရင်း (လက်တင်)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ဆားဘီးယား (စီရီလစ်)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"မွန်တီနီဂရင်း (စီရီလစ်)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ရိုမေးနီးယား"</string> </resources> diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml index 7ac2a822667a..954462c783ff 100644 --- a/packages/InputDevices/res/values-nb/strings.xml +++ b/packages/InputDevices/res/values-nb/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrisk (latinsk)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisk (kyrillisk)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrisk (kyrillisk)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumensk"</string> </resources> diff --git a/packages/InputDevices/res/values-ne/strings.xml b/packages/InputDevices/res/values-ne/strings.xml index 113489d65d96..e2804d4a89b5 100644 --- a/packages/InputDevices/res/values-ne/strings.xml +++ b/packages/InputDevices/res/values-ne/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"मोन्टेनिग्रिन (ल्याटिन)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"सर्बियाली (सिरिलिक)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"मोन्टेनिग्रिन (सिरिलिक)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"रोमानियाली"</string> </resources> diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml index 0e954e9b9ed3..67f78bad4158 100644 --- a/packages/InputDevices/res/values-nl/strings.xml +++ b/packages/InputDevices/res/values-nl/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrijns (Latijns)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Servisch (Cyrillisch)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrijns (Cyrillisch)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Roemeens"</string> </resources> diff --git a/packages/InputDevices/res/values-or/strings.xml b/packages/InputDevices/res/values-or/strings.xml index d9d852008275..c6e020cae6d0 100644 --- a/packages/InputDevices/res/values-or/strings.xml +++ b/packages/InputDevices/res/values-or/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ମଣ୍ଟେନେଗ୍ରିନ (ଲାଟିନ)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ସର୍ବିଆନ (ସିରିଲିକ)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ମଣ୍ଟେନେଗ୍ରିନ (ସିରିଲିକ)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ରୋମାନିଆନ"</string> </resources> diff --git a/packages/InputDevices/res/values-pa/strings.xml b/packages/InputDevices/res/values-pa/strings.xml index 85b0d195f05f..29c3b7d14bb2 100644 --- a/packages/InputDevices/res/values-pa/strings.xml +++ b/packages/InputDevices/res/values-pa/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"ਮਾਂਟੇਨੀਗਰਿਨ (ਲਾਤੀਨੀ)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"ਸਰਬੀਆਈ (ਸਿਰਿਲਿਕ)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"ਮਾਂਟੇਨੀਗਰਿਨ (ਸਿਰਿਲਿਕ)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ਰੋਮਾਨੀਆਈ"</string> </resources> diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml index 7fb90d2454f6..8ce00d3947b8 100644 --- a/packages/InputDevices/res/values-pl/strings.xml +++ b/packages/InputDevices/res/values-pl/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"czarnogórski (alfabet łaciński)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbski (cyrylica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"czarnogórski (cyrylica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumuński"</string> </resources> diff --git a/packages/InputDevices/res/values-pt-rBR/strings.xml b/packages/InputDevices/res/values-pt-rBR/strings.xml index 2b92c811be64..3b1fc9b888d9 100644 --- a/packages/InputDevices/res/values-pt-rBR/strings.xml +++ b/packages/InputDevices/res/values-pt-rBR/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string> </resources> diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml index 98cf7e2df754..163108d94367 100644 --- a/packages/InputDevices/res/values-pt-rPT/strings.xml +++ b/packages/InputDevices/res/values-pt-rPT/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string> </resources> diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml index 2b92c811be64..3b1fc9b888d9 100644 --- a/packages/InputDevices/res/values-pt/strings.xml +++ b/packages/InputDevices/res/values-pt/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrino (latim)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sérvio (cirílico)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrino (cirílico)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romeno"</string> </resources> diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml index 71d19958263e..78c99ce4e20e 100644 --- a/packages/InputDevices/res/values-ro/strings.xml +++ b/packages/InputDevices/res/values-ro/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Muntenegreană (caractere latine)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sârbă (caractere chirilice)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Muntenegreană (Chirilică)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Română"</string> </resources> diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml index 13130fc9ca1f..183b00e203b4 100644 --- a/packages/InputDevices/res/values-ru/strings.xml +++ b/packages/InputDevices/res/values-ru/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Черногорский (латиница)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербский (кириллица)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Черногорский (кириллица)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Румынский"</string> </resources> diff --git a/packages/InputDevices/res/values-si/strings.xml b/packages/InputDevices/res/values-si/strings.xml index 80c674d00bca..373dfda87874 100644 --- a/packages/InputDevices/res/values-si/strings.xml +++ b/packages/InputDevices/res/values-si/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"මොන්ටෙනේග්රීන් (ලතින්)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"සර්බියානු (සිරිලික්)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"මොන්ටෙනේග්රීන් (සිරිලික්)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml index 6ce98cc34bca..c269085202b6 100644 --- a/packages/InputDevices/res/values-sk/strings.xml +++ b/packages/InputDevices/res/values-sk/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"čiernohorčina (latinka)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbčina (cyrilika)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"čiernohorčina (cyrilika)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumunčina"</string> </resources> diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml index 29264231e6f6..d2e9fd182d21 100644 --- a/packages/InputDevices/res/values-sl/strings.xml +++ b/packages/InputDevices/res/values-sl/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"črnogorščina (latinica)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"srbščina (cirilica)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"črnogorščina (cirilica)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"romunščina"</string> </resources> diff --git a/packages/InputDevices/res/values-sq/strings.xml b/packages/InputDevices/res/values-sq/strings.xml index 06f76f3d6c4a..36882cbf7986 100644 --- a/packages/InputDevices/res/values-sq/strings.xml +++ b/packages/InputDevices/res/values-sq/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Malazisht (latine)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbisht (cirilike)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Malazisht (cirilike)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml index 1172fef2c0a9..e4fed039668f 100644 --- a/packages/InputDevices/res/values-sr/strings.xml +++ b/packages/InputDevices/res/values-sr/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"црногорски (латиница)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"српски (ћирилица)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"црногорски (ћирилица)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"румунски"</string> </resources> diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml index 946854ca00bb..4eaf856adde9 100644 --- a/packages/InputDevices/res/values-sv/strings.xml +++ b/packages/InputDevices/res/values-sv/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"montenegrinska (latinskt)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"serbiska (kyrilliskt)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"montenegrinska (kyrilliskt)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"rumänska"</string> </resources> diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml index c3578d8b5fbd..30b52b25468c 100644 --- a/packages/InputDevices/res/values-sw/strings.xml +++ b/packages/InputDevices/res/values-sw/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Kimontenegri (Kilatini)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Kiserbia (Kisiriliki)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Kimontenegri (Kisiriliki)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Kiromania"</string> </resources> diff --git a/packages/InputDevices/res/values-ta/strings.xml b/packages/InputDevices/res/values-ta/strings.xml index 5c3f57e361b7..d60084cd62f7 100644 --- a/packages/InputDevices/res/values-ta/strings.xml +++ b/packages/InputDevices/res/values-ta/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"மாண்டினெக்ரன் (லத்தீன்)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"செர்பியன் (சிரிலிக்)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"மாண்டினெக்ரன் (சிரிலிக்)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"ரோமானியன்"</string> </resources> diff --git a/packages/InputDevices/res/values-te/strings.xml b/packages/InputDevices/res/values-te/strings.xml index a0674d665ed9..2f40442de757 100644 --- a/packages/InputDevices/res/values-te/strings.xml +++ b/packages/InputDevices/res/values-te/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"మాంటెనెగ్రిన్ (లాటిన్)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"సెర్బియన్ (సిరిలిక్)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"మాంటెనెగ్రిన్ (సిరిలిక్)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"రొమేనియన్"</string> </resources> diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml index a9465961f06a..ae10f0409760 100644 --- a/packages/InputDevices/res/values-th/strings.xml +++ b/packages/InputDevices/res/values-th/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"มอนเตเนโกร (ละติน)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"เซอร์เบีย (ซีริลลิก)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"มอนเตเนโกร (ซีริลลิก)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"โรมาเนีย"</string> </resources> diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml index 0a5d3cc6c1d6..dc0d1f52fe8f 100644 --- a/packages/InputDevices/res/values-tl/strings.xml +++ b/packages/InputDevices/res/values-tl/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Romanian"</string> </resources> diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml index f37a098f0714..2e7084d43cdd 100644 --- a/packages/InputDevices/res/values-tr/strings.xml +++ b/packages/InputDevices/res/values-tr/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Karadağca (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Sırpça (Kiril)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Karadağca (Kiril)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Rumence"</string> </resources> diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml index d496dfa3910b..1010177539b1 100644 --- a/packages/InputDevices/res/values-uk/strings.xml +++ b/packages/InputDevices/res/values-uk/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Чорногорська (латиниця)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Сербська (кирилиця)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Чорногорська (кирилиця)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-ur/strings.xml b/packages/InputDevices/res/values-ur/strings.xml index 7293858ee413..94cd329ff442 100644 --- a/packages/InputDevices/res/values-ur/strings.xml +++ b/packages/InputDevices/res/values-ur/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"مونٹے نیگریائی (لاطینی)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"سربیائی (سیریلک)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"مونٹے نیگریائی (سیریلک)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"رومانیائی"</string> </resources> diff --git a/packages/InputDevices/res/values-uz/strings.xml b/packages/InputDevices/res/values-uz/strings.xml index f212e2c4108e..92e00d81c622 100644 --- a/packages/InputDevices/res/values-uz/strings.xml +++ b/packages/InputDevices/res/values-uz/strings.xml @@ -56,4 +56,6 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Chernogor (lotin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serb (kirill)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Chernogor (kirill)"</string> + <!-- no translation found for keyboard_layout_romanian (8698989892731726903) --> + <skip /> </resources> diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml index f3d2cc48fb96..8384c3ec0652 100644 --- a/packages/InputDevices/res/values-vi/strings.xml +++ b/packages/InputDevices/res/values-vi/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Tiếng Montenegro (Latinh)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Tiếng Serbia (Chữ Kirin)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Tiếng Montenegro (Chữ Kirin)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"Tiếng Romania"</string> </resources> diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml index 1f74d3436557..e3a8af367d70 100644 --- a/packages/InputDevices/res/values-zh-rCN/strings.xml +++ b/packages/InputDevices/res/values-zh-rCN/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"黑山语(拉丁字母)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞尔维亚语(西里尔字母)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"黑山语(西里尔字母)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"罗马尼亚语"</string> </resources> diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml index 9c6864a7bec6..56681b8d3ece 100644 --- a/packages/InputDevices/res/values-zh-rHK/strings.xml +++ b/packages/InputDevices/res/values-zh-rHK/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"蒙特內哥羅文 (拉丁)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"羅馬尼亞文"</string> </resources> diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml index f4159c983bb4..60c085bb2bac 100644 --- a/packages/InputDevices/res/values-zh-rTW/strings.xml +++ b/packages/InputDevices/res/values-zh-rTW/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"蒙特內哥羅文 (拉丁字母)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"塞爾維亞文 (西里爾字母)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"蒙特內哥羅文 (西里爾字母)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"羅馬尼亞文"</string> </resources> diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml index ead5a4557901..66973333fa75 100644 --- a/packages/InputDevices/res/values-zu/strings.xml +++ b/packages/InputDevices/res/values-zu/strings.xml @@ -56,4 +56,5 @@ <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"IsiMontenegrin (Latin)"</string> <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string> <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string> + <string name="keyboard_layout_romanian" msgid="8698989892731726903">"IsiRomanian"</string> </resources> diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml index f26ac2d0229a..4789f8bcc83a 100644 --- a/packages/PackageInstaller/res/values-kn/strings.xml +++ b/packages/PackageInstaller/res/values-kn/strings.xml @@ -91,7 +91,7 @@ <string name="manage_device_administrators" msgid="3092696419363842816">"ಸಾಧನದ ನಿರ್ವಹಣೆ ಆ್ಯಪ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="manage_users" msgid="1243995386982560813">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string> <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> - <string name="Parse_error_dlg_text" msgid="1661404001063076789">"ಪ್ಯಾಕೇಜ್ ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ ಕಂಡುಬಂದಿದೆ."</string> + <string name="Parse_error_dlg_text" msgid="1661404001063076789">"ಪ್ಯಾಕೇಜ್ ಪಾರ್ಸ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಕಂಡುಬಂದಿದೆ."</string> <string name="message_staging" msgid="8032722385658438567">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಸಿದ್ಧವಿರುವ ಆ್ಯಪ್…"</string> <string name="app_name_unknown" msgid="6881210203354323926">"ಅಪರಿಚಿತ"</string> <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಆ್ಯಪ್ಗಳನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಪ್ರಸ್ತುತ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ಗೆ ಅನುಮತಿಯಿಲ್ಲ. ನೀವು ಇದನ್ನು ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು."</string> diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index 933c512313ce..e5b58370e6dd 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -46,6 +46,8 @@ android_library { "SettingsLibIntroPreference", "SettingsLibLayoutPreference", "SettingsLibMainSwitchPreference", + "SettingsLibMetadata", + "SettingsLibPreference", "SettingsLibProfileSelector", "SettingsLibProgressBar", "SettingsLibRestrictedLockUtils", @@ -77,6 +79,7 @@ android_library { "src/**/*.kt", "src/**/I*.aidl", ], + kotlincflags: ["-Xjvm-default=all"], } // defaults for lint option diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt index f001fad69dc6..ce66a360a99f 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceGraphBuilder.kt @@ -40,8 +40,6 @@ import com.android.settingslib.graph.proto.PreferenceProto import com.android.settingslib.graph.proto.PreferenceProto.ActionTarget import com.android.settingslib.graph.proto.PreferenceScreenProto import com.android.settingslib.graph.proto.TextProto -import com.android.settingslib.metadata.BooleanValue -import com.android.settingslib.metadata.FloatPersistentPreference import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceHierarchy @@ -410,26 +408,33 @@ fun PreferenceMetadata.toProto( val storage = metadata.storage(context) value = preferenceValueProto { when (metadata) { - is BooleanValue -> storage.getBoolean(metadata.key)?.let { booleanValue = it } is RangeValue -> storage.getInt(metadata.key)?.let { intValue = it } - is FloatPersistentPreference -> - storage.getFloat(metadata.key)?.let { floatValue = it } else -> {} } + when (metadata.valueType) { + Boolean::class.javaObjectType -> + storage.getBoolean(metadata.key)?.let { booleanValue = it } + Float::class.javaObjectType -> + storage.getFloat(metadata.key)?.let { floatValue = it } + } } } if (flags.includeValueDescriptor()) { valueDescriptor = preferenceValueDescriptorProto { when (metadata) { - is BooleanValue -> booleanType = true is RangeValue -> rangeValue = rangeValueProto { min = metadata.getMinValue(context) max = metadata.getMaxValue(context) step = metadata.getIncrementStep(context) } - is FloatPersistentPreference -> floatType = true else -> {} } + if (metadata is PersistentPreference<*>) { + when (metadata.valueType) { + Boolean::class.javaObjectType -> booleanType = true + Float::class.javaObjectType -> floatType = true + } + } } } } diff --git a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt index ea795542a5f6..47190648810a 100644 --- a/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt +++ b/packages/SettingsLib/Graph/src/com/android/settingslib/graph/PreferenceSetterApi.kt @@ -26,7 +26,6 @@ import com.android.settingslib.ipc.ApiHandler import com.android.settingslib.ipc.ApiPermissionChecker import com.android.settingslib.ipc.IntMessageCodec import com.android.settingslib.ipc.MessageCodec -import com.android.settingslib.metadata.BooleanValue import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceAvailabilityProvider import com.android.settingslib.metadata.PreferenceMetadata @@ -146,7 +145,9 @@ class PreferenceSetterApiHandler( val value = request.value try { if (value.hasBooleanValue()) { - if (metadata !is BooleanValue) return PreferenceSetterResult.INVALID_REQUEST + if (metadata.valueType != Boolean::class.javaObjectType) { + return PreferenceSetterResult.INVALID_REQUEST + } val booleanValue = value.booleanValue val resultCode = metadata.checkWritePermit(booleanValue) if (resultCode != PreferenceSetterResult.OK) return resultCode diff --git a/packages/SettingsLib/IllustrationPreference/res/drawable/protection_background_tablet.xml b/packages/SettingsLib/IllustrationPreference/res/drawable/protection_background_tablet.xml new file mode 100644 index 000000000000..31714b7ff902 --- /dev/null +++ b/packages/SettingsLib/IllustrationPreference/res/drawable/protection_background_tablet.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2025 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. +--> + +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item> + <shape android:shape="rectangle"> + <solid android:color="@color/settingslib_protection_color"/> + <corners android:radius="28dp"/> + <size android:width="@dimen/settingslib_illustration_width_tablet" + android:height="@dimen/settingslib_illustration_height_tablet"/> + </shape> + </item> +</layer-list> diff --git a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml index 0ae9c2674bc7..fcc2a04201dd 100644 --- a/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml +++ b/packages/SettingsLib/IllustrationPreference/res/layout/illustration_preference.xml @@ -40,6 +40,15 @@ android:adjustViewBounds="true" android:src="@drawable/protection_background"/> + <ImageView + android:id="@+id/background_view_tablet" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:adjustViewBounds="true" + android:src="@drawable/protection_background_tablet" + android:visibility="gone"/> + <com.airbnb.lottie.LottieAnimationView android:id="@+id/lottie_view" android:layout_width="wrap_content" diff --git a/packages/SettingsLib/IllustrationPreference/res/values/dimens.xml b/packages/SettingsLib/IllustrationPreference/res/values/dimens.xml index fc273dc7403b..7b5012efd783 100644 --- a/packages/SettingsLib/IllustrationPreference/res/values/dimens.xml +++ b/packages/SettingsLib/IllustrationPreference/res/values/dimens.xml @@ -21,4 +21,7 @@ <dimen name="settingslib_illustration_width">412dp</dimen> <dimen name="settingslib_illustration_height">300dp</dimen> + + <dimen name="settingslib_illustration_width_tablet">498dp</dimen> + <dimen name="settingslib_illustration_height_tablet">362dp</dimen> </resources> diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java index bc4f1f942dc0..4b407c50bbd5 100644 --- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java +++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java @@ -72,6 +72,7 @@ public class IllustrationPreference extends Preference implements GroupSectionDi private OnBindListener mOnBindListener; private boolean mLottieDynamicColor; private CharSequence mContentDescription; + private boolean mIsTablet; /** * Interface to listen in on when {@link #onBindViewHolder(PreferenceViewHolder)} occurs. @@ -127,8 +128,17 @@ public class IllustrationPreference extends Preference implements GroupSectionDi final FrameLayout illustrationFrame = (FrameLayout) holder.findViewById( R.id.illustration_frame); - final ImageView backgroundView = + ImageView backgroundView = (ImageView) holder.findViewById(R.id.background_view); + ImageView backgroundViewTablet = + (ImageView) holder.findViewById(R.id.background_view_tablet); + + backgroundView.setVisibility(mIsTablet ? View.GONE : View.VISIBLE); + backgroundViewTablet.setVisibility(mIsTablet ? View.VISIBLE : View.GONE); + if (mIsTablet) { + backgroundView = backgroundViewTablet; + } + final FrameLayout middleGroundLayout = (FrameLayout) holder.findViewById(R.id.middleground_layout); final LottieAnimationView illustrationView = @@ -413,7 +423,7 @@ public class IllustrationPreference extends Preference implements GroupSectionDi final Resources res = backgroundView.getResources(); final int frameWidth = res.getDimensionPixelSize(R.dimen.settingslib_illustration_width); final int frameHeight = res.getDimensionPixelSize(R.dimen.settingslib_illustration_height); - final int restrictedMaxHeight = Math.min(mMaxHeight, frameHeight); + final int restrictedMaxHeight = mMaxHeight; backgroundView.setMaxHeight(restrictedMaxHeight); illustrationView.setMaxHeight(restrictedMaxHeight); @@ -505,5 +515,11 @@ public class IllustrationPreference extends Preference implements GroupSectionDi a.recycle(); } + mIsTablet = SettingsThemeHelper.isExpressiveTheme(context) + && SettingsThemeHelper.isTablet(context); + if (mIsTablet) { + setMaxHeight(context.getResources().getDimensionPixelSize( + R.dimen.settingslib_illustration_height_tablet)); + } } } diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Metrics.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Metrics.kt new file mode 100644 index 000000000000..7323488c5299 --- /dev/null +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/Metrics.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2025 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.settingslib.metadata + +/** Metrics logger for preference actions triggered by user interaction. */ +interface PreferenceUiActionMetricsLogger { + + /** + * Logs preference value change due to user interaction. + * + * Note: Preference value changed by external Set is excluded. + */ + fun logPreferenceValueChange( + screen: PreferenceScreenMetadata, + preference: PreferenceMetadata, + value: Any?, + ) {} +} + +/** Metrics logger for preference remote operations (e.g. external get/set). */ +interface PreferenceRemoteOpMetricsLogger diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt index 83725aaec377..8e850465ef7d 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PersistentPreference.kt @@ -79,6 +79,14 @@ annotation class SensitivityLevel { interface PersistentPreference<T> { /** + * The value type the preference is associated with. + * + * TODO(b/388167302): Remove the default implementation once all subclasses are migrated. + */ + val valueType: Class<T>? + get() = null + + /** * Returns the key-value storage of the preference. * * The default implementation returns the storage provided by @@ -143,15 +151,6 @@ sealed interface ValueDescriptor { fun isValidValue(context: Context, index: Int): Boolean } -/** - * A boolean type value. - * - * A zero value means `False`, otherwise it is `True`. - */ -interface BooleanValue : ValueDescriptor { - override fun isValidValue(context: Context, index: Int) = true -} - /** Value falls into a given array. */ interface DiscreteValue<T> : ValueDescriptor { @get:ArrayRes val values: Int @@ -220,6 +219,3 @@ interface RangeValue : ValueDescriptor { override fun isValidValue(context: Context, index: Int) = index in getMinValue(context)..getMaxValue(context) } - -/** A persistent preference that has a float value. */ -interface FloatPersistentPreference : PersistentPreference<Float> diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt index 9fc21343b6a0..c74b3151abb2 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceScreenRegistry.kt @@ -32,6 +32,9 @@ object PreferenceScreenRegistry : ReadWritePermitProvider { */ var preferenceScreenMetadataFactories = FixedArrayMap<String, PreferenceScreenMetadataFactory>() + /** Metrics logger for preference actions triggered by user interaction. */ + var preferenceUiActionMetricsLogger: PreferenceUiActionMetricsLogger? = null + private var readWritePermitProvider: ReadWritePermitProvider = object : ReadWritePermitProvider {} diff --git a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt index 87bd261bf4bd..623ea22410e5 100644 --- a/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt +++ b/packages/SettingsLib/Metadata/src/com/android/settingslib/metadata/PreferenceTypes.kt @@ -18,8 +18,20 @@ package com.android.settingslib.metadata import androidx.annotation.StringRes +/** A persistent preference that has a boolean value. */ +interface BooleanValuePreference : PersistentPreference<Boolean> { + override val valueType: Class<Boolean> + get() = Boolean::class.javaObjectType +} + +/** A persistent preference that has a float value. */ +interface FloatValuePreference : PersistentPreference<Float> { + override val valueType: Class<Float> + get() = Float::class.javaObjectType +} + /** Common base class for preferences that have two selectable states and save a boolean value. */ -interface TwoStatePreference : PreferenceMetadata, PersistentPreference<Boolean>, BooleanValue +interface TwoStatePreference : PreferenceMetadata, BooleanValuePreference /** A preference that provides a two-state toggleable option. */ open class SwitchPreference diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt index 6b7be91c1903..c61c6a5c75fa 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBinding.kt @@ -17,6 +17,7 @@ package com.android.settingslib.preference import android.content.Context +import androidx.annotation.CallSuper import androidx.preference.DialogPreference import androidx.preference.ListPreference import androidx.preference.Preference @@ -59,6 +60,7 @@ interface PreferenceBinding { * @param preference preference widget created by [createWidget] * @param metadata metadata to apply */ + @CallSuper fun bind(preference: Preference, metadata: PreferenceMetadata) { metadata.apply { preference.key = key diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindings.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindings.kt index bd5d17cb2468..b82c554ea26a 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindings.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceBindings.kt @@ -45,7 +45,7 @@ interface PreferenceScreenBinding : PreferenceBinding { context.getString(screenTitle) } else { screenMetadata.getScreenTitle(context) - ?: (this as? PreferenceTitleProvider)?.getTitle(context) + ?: (screenMetadata as? PreferenceTitleProvider)?.getTitle(context) } } } diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreDelegate.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreDelegate.kt new file mode 100644 index 000000000000..482eaf9146e5 --- /dev/null +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceDataStoreDelegate.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2025 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.settingslib.preference + +import androidx.preference.PreferenceDataStore + +/** [PreferenceDataStore] delegate. */ +open class PreferenceDataStoreDelegate(internal val delegate: PreferenceDataStore) : + PreferenceDataStore() { + + override fun getBoolean(key: String, defValue: Boolean): Boolean = + delegate.getBoolean(key, defValue) + + override fun getFloat(key: String, defValue: Float): Float = delegate.getFloat(key, defValue) + + override fun getInt(key: String, defValue: Int): Int = delegate.getInt(key, defValue) + + override fun getLong(key: String, defValue: Long): Long = delegate.getLong(key, defValue) + + override fun getString(key: String, defValue: String?): String? = + delegate.getString(key, defValue) + + override fun getStringSet(key: String, defValues: Set<String>?): Set<String>? = + delegate.getStringSet(key, defValues) + + override fun putBoolean(key: String, value: Boolean) = delegate.putBoolean(key, value) + + override fun putFloat(key: String, value: Float) = delegate.putFloat(key, value) + + override fun putInt(key: String, value: Int) = delegate.putInt(key, value) + + override fun putLong(key: String, value: Long) = delegate.putLong(key, value) + + override fun putString(key: String, value: String?) = delegate.putString(key, value) + + override fun putStringSet(key: String, values: Set<String>?) = + delegate.putStringSet(key, values) +} diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt index e237a6a4cf14..ffe181d0c350 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceFragment.kt @@ -21,6 +21,7 @@ import android.content.Intent import android.os.Bundle import android.util.Log import androidx.annotation.XmlRes +import androidx.lifecycle.Lifecycle import androidx.preference.PreferenceScreen import com.android.settingslib.metadata.EXTRA_BINDING_SCREEN_KEY import com.android.settingslib.metadata.PreferenceScreenBindingKeyProvider @@ -38,6 +39,11 @@ open class PreferenceFragment : preferenceScreen = createPreferenceScreen() } + override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) { + super.setPreferenceScreen(preferenceScreen) + updateActivityTitle() + } + fun createPreferenceScreen(): PreferenceScreen? = createPreferenceScreen(PreferenceScreenFactory(this)) @@ -102,9 +108,19 @@ open class PreferenceFragment : override fun onResume() { super.onResume() + // Even when activity has several fragments with preference screen, this will keep activity + // title in sync when fragment manager pops back stack. + updateActivityTitle() preferenceScreenBindingHelper?.onResume() } + internal fun updateActivityTitle() { + if (!lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) return + val activity = activity ?: return + val title = preferenceScreen?.title ?: return + if (activity.title != title) activity.title = title + } + override fun onPause() { preferenceScreenBindingHelper?.onPause() super.onPause() diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceHierarchyInflater.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceHierarchyInflater.kt index 657f69a738f2..f3f854c0dc47 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceHierarchyInflater.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceHierarchyInflater.kt @@ -18,15 +18,30 @@ package com.android.settingslib.preference import androidx.preference.PreferenceDataStore import androidx.preference.PreferenceGroup +import androidx.preference.PreferenceScreen import com.android.settingslib.datastore.KeyValueStore import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceHierarchy +import com.android.settingslib.metadata.PreferenceScreenMetadata /** Inflates [PreferenceHierarchy] into given [PreferenceGroup] recursively. */ -fun PreferenceGroup.inflatePreferenceHierarchy( +fun PreferenceScreen.inflatePreferenceHierarchy( preferenceBindingFactory: PreferenceBindingFactory, hierarchy: PreferenceHierarchy, - storages: MutableMap<KeyValueStore, PreferenceDataStore> = mutableMapOf(), +) = + inflatePreferenceHierarchy( + hierarchy.metadata as PreferenceScreenMetadata, + preferenceBindingFactory, + hierarchy, + mutableMapOf(), + ) + +/** Inflates [PreferenceHierarchy] into given [PreferenceGroup] recursively. */ +private fun PreferenceGroup.inflatePreferenceHierarchy( + preferenceScreenMetadata: PreferenceScreenMetadata, + preferenceBindingFactory: PreferenceBindingFactory, + hierarchy: PreferenceHierarchy, + storages: MutableMap<KeyValueStore, PreferenceDataStore>, ) { preferenceBindingFactory.bind(this, hierarchy) hierarchy.forEach { @@ -38,11 +53,18 @@ fun PreferenceGroup.inflatePreferenceHierarchy( val preferenceGroup = widget as PreferenceGroup // MUST add preference before binding, otherwise exception is raised when add child addPreference(preferenceGroup) - preferenceGroup.inflatePreferenceHierarchy(preferenceBindingFactory, it) + preferenceGroup.inflatePreferenceHierarchy( + preferenceScreenMetadata, + preferenceBindingFactory, + it, + storages, + ) } else { (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage -> widget.preferenceDataStore = - storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) } + storages.getOrPut(storage) { + storage.toPreferenceDataStore(preferenceScreenMetadata, metadata) + } } preferenceBindingFactory.bind(widget, it, preferenceBinding) // MUST add preference after binding for persistent preference to get initial value diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt index 8358ab921fb6..4a6a589cd3c9 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/PreferenceScreenBindingHelper.kt @@ -38,6 +38,7 @@ import com.android.settingslib.metadata.PreferenceHierarchyNode import com.android.settingslib.metadata.PreferenceLifecycleContext import com.android.settingslib.metadata.PreferenceLifecycleProvider import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.PreferenceScreenMetadata import com.android.settingslib.metadata.PreferenceScreenRegistry import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableMultimap @@ -51,7 +52,7 @@ import com.google.common.collect.ImmutableMultimap */ class PreferenceScreenBindingHelper( context: Context, - fragment: PreferenceFragment, + private val fragment: PreferenceFragment, private val preferenceBindingFactory: PreferenceBindingFactory, private val preferenceScreen: PreferenceScreen, private val preferenceHierarchy: PreferenceHierarchy, @@ -70,9 +71,7 @@ class PreferenceScreenBindingHelper( override fun <T : Any> requirePreference(key: String) = findPreference<T>(key)!! override fun getKeyValueStore(key: String) = - (findPreference<Preference>(key)?.preferenceDataStore - as? PreferenceDataStoreAdapter) - ?.keyValueStore + findPreference<Preference>(key)?.preferenceDataStore?.findKeyValueStore() override fun notifyPreferenceChange(key: String) = notifyChange(key, PreferenceChangeReason.STATE) @@ -137,22 +136,29 @@ class PreferenceScreenBindingHelper( addObserver(preferenceObserver, mainExecutor) preferenceScreen.forEachRecursively { - val preferenceDataStore = it.preferenceDataStore - if (preferenceDataStore is PreferenceDataStoreAdapter) { + it.preferenceDataStore?.findKeyValueStore()?.let { keyValueStore -> val key = it.key - val keyValueStore = preferenceDataStore.keyValueStore storages[key] = keyValueStore keyValueStore.addObserver(key, storageObserver, mainExecutor) } } } + private fun PreferenceDataStore.findKeyValueStore(): KeyValueStore? = + when (this) { + is PreferenceDataStoreAdapter -> keyValueStore + is PreferenceDataStoreDelegate -> delegate.findKeyValueStore() + else -> null + } + private fun onPreferenceChange(key: String?, reason: Int) { if (key == null) return // bind preference to update UI preferenceScreen.findPreference<Preference>(key)?.let { - preferences[key]?.let { node -> preferenceBindingFactory.bind(it, node) } + val node = preferences[key] ?: return@let + preferenceBindingFactory.bind(it, node) + if (it == preferenceScreen) fragment.updateActivityTitle() } // check reason to avoid potential infinite loop @@ -239,17 +245,17 @@ class PreferenceScreenBindingHelper( preferenceBindingFactory: PreferenceBindingFactory, preferenceHierarchy: PreferenceHierarchy, ) { + val preferenceScreenMetadata = preferenceHierarchy.metadata as PreferenceScreenMetadata val preferences = mutableMapOf<String, PreferenceHierarchyNode>() - preferenceHierarchy.forEachRecursively { - val metadata = it.metadata - preferences[metadata.key] = it - } + preferenceHierarchy.forEachRecursively { preferences[it.metadata.key] = it } val storages = mutableMapOf<KeyValueStore, PreferenceDataStore>() fun Preference.setPreferenceDataStore(metadata: PreferenceMetadata) { (metadata as? PersistentPreference<*>)?.storage(context)?.let { storage -> preferenceDataStore = - storages.getOrPut(storage) { PreferenceDataStoreAdapter(storage) } + storages.getOrPut(storage) { + storage.toPreferenceDataStore(preferenceScreenMetadata, metadata) + } } } diff --git a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt index 2e7221bd4d7f..f5ab4b2e38d8 100644 --- a/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt +++ b/packages/SettingsLib/Preference/src/com/android/settingslib/preference/Utils.kt @@ -17,7 +17,12 @@ package com.android.settingslib.preference import androidx.preference.Preference +import androidx.preference.PreferenceDataStore import androidx.preference.PreferenceGroup +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.PreferenceScreenMetadata +import com.android.settingslib.metadata.PreferenceScreenRegistry /** Traversals preference hierarchy recursively and applies an action. */ fun PreferenceGroup.forEachRecursively(action: (Preference) -> Unit) { @@ -31,3 +36,51 @@ fun PreferenceGroup.forEachRecursively(action: (Preference) -> Unit) { } } } + +/** + * Converts [KeyValueStore] to [PreferenceDataStore]. + * + * [PreferenceScreenRegistry.preferenceUiActionMetricsLogger] is wrapped on top of + * [PreferenceDataStoreDelegate] to log metrics. + * + * Note: Only user interaction changes are logged. + */ +fun KeyValueStore.toPreferenceDataStore( + screen: PreferenceScreenMetadata, + preference: PreferenceMetadata, +): PreferenceDataStore { + val preferenceDataStore: PreferenceDataStore = PreferenceDataStoreAdapter(this) + val metricsLogger = + PreferenceScreenRegistry.preferenceUiActionMetricsLogger ?: return preferenceDataStore + return object : PreferenceDataStoreDelegate(preferenceDataStore) { + override fun putBoolean(key: String, value: Boolean) { + super.putBoolean(key, value) + metricsLogger.logPreferenceValueChange(screen, preference, value) + } + + override fun putFloat(key: String, value: Float) { + super.putFloat(key, value) + metricsLogger.logPreferenceValueChange(screen, preference, value) + } + + override fun putInt(key: String, value: Int) { + super.putInt(key, value) + metricsLogger.logPreferenceValueChange(screen, preference, value) + } + + override fun putLong(key: String, value: Long) { + super.putLong(key, value) + metricsLogger.logPreferenceValueChange(screen, preference, value) + } + + override fun putString(key: String, value: String?) { + super.putString(key, value) + metricsLogger.logPreferenceValueChange(screen, preference, value) + } + + override fun putStringSet(key: String, values: Set<String>?) { + super.putStringSet(key, values) + metricsLogger.logPreferenceValueChange(screen, preference, values) + } + } +} diff --git a/packages/SettingsLib/Preference/testutils/Android.bp b/packages/SettingsLib/Preference/testutils/Android.bp index 5287d6ce93f1..68b724280ac1 100644 --- a/packages/SettingsLib/Preference/testutils/Android.bp +++ b/packages/SettingsLib/Preference/testutils/Android.bp @@ -27,6 +27,7 @@ android_library { "androidx.test.core", "androidx.test.ext.junit", "flag-junit", + "mockito-kotlin2", "truth", ], } diff --git a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt index 220614bf064f..172c68a4bd37 100644 --- a/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt +++ b/packages/SettingsLib/Preference/testutils/com/android/settingslib/preference/PreferenceBindingTestUtils.kt @@ -22,6 +22,8 @@ import androidx.preference.Preference import androidx.preference.PreferenceScreen import com.android.settingslib.metadata.PersistentPreference import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.metadata.PreferenceScreenMetadata +import org.mockito.kotlin.mock /** Creates [Preference] widget and binds with metadata. */ @Suppress("UNCHECKED_CAST") @@ -29,13 +31,13 @@ import com.android.settingslib.metadata.PreferenceMetadata fun <P : Preference> PreferenceMetadata.createAndBindWidget( context: Context, preferenceScreen: PreferenceScreen? = null, + preferenceScreenMetadata: PreferenceScreenMetadata = mock(), ): P { val binding = PreferenceBindingFactory.defaultFactory.getPreferenceBinding(this)!! return (binding.createWidget(context) as P).also { if (this is PersistentPreference<*>) { - storage(context).let { keyValueStore -> - it.preferenceDataStore = PreferenceDataStoreAdapter(keyValueStore) - } + it.preferenceDataStore = + storage(context).toPreferenceDataStore(preferenceScreenMetadata, this) // Attach preference to preference screen, otherwise `Preference.performClick` does not // interact with underlying datastore (preferenceScreen ?: PreferenceScreenFactory(context).getOrCreatePreferenceScreen()) diff --git a/packages/SettingsLib/SearchWidget/res/values-as/strings.xml b/packages/SettingsLib/SearchWidget/res/values-as/strings.xml index 8d95131e0e15..8c1bd4024595 100644 --- a/packages/SettingsLib/SearchWidget/res/values-as/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-as/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"সন্ধান সম্পৰ্কীয় ছেটিং"</string> + <string name="search_menu" msgid="1914043873178389845">"ছেটিঙত সন্ধান কৰক"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml index d38510189507..db02f002b935 100644 --- a/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"Buscar configuración"</string> + <string name="search_menu" msgid="1914043873178389845">"Buscar en Configuración"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml index a1bb54e07260..258208473ade 100644 --- a/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"Пребарување низ поставките"</string> + <string name="search_menu" msgid="1914043873178389845">"Пребарувајте низ поставките"</string> </resources> diff --git a/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml index 09a285b7452f..97497c18c621 100644 --- a/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1914043873178389845">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਖੋਜੋ"</string> + <string name="search_menu" msgid="1914043873178389845">"ਸੈਟਿੰਗਾਂ ਖੋਜੋ"</string> </resources> diff --git a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml index 2776544e2948..7d7bec14ed78 100644 --- a/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml +++ b/packages/SettingsLib/SettingsTheme/res/layout-v35/settingslib_expressive_collapsable_textview.xml @@ -48,6 +48,7 @@ android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@android:id/title" app:layout_constraintStart_toStartOf="parent" + android:paddingTop="@dimen/settingslib_expressive_space_extrasmall6" android:textAlignment="viewStart" android:clickable="true" android:visibility="gone" diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml index b6e80c784f10..dc5c9b297181 100644 --- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml +++ b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml @@ -18,7 +18,7 @@ <resources> <style name="Theme.SettingsBase_v35" parent="Theme.SettingsBase_v33" > <item name="android:colorAccent">@color/settingslib_materialColorPrimary</item> - <item name="android:colorBackground">@color/settingslib_materialColorSurfaceContainer</item> + <item name="android:colorBackground">@color/settingslib_materialColorSurfaceContainerLowest</item> <item name="android:textColorPrimary">@color/settingslib_materialColorOnSurface</item> <item name="android:textColorSecondary">@color/settingslib_text_color_secondary</item> <item name="android:textColorTertiary">@color/settingslib_materialColorOutline</item> diff --git a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsThemeHelper.kt b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsThemeHelper.kt index 74f5441f6760..6794cd0e30a2 100644 --- a/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsThemeHelper.kt +++ b/packages/SettingsLib/SettingsTheme/src/com/android/settingslib/widget/SettingsThemeHelper.kt @@ -21,6 +21,7 @@ import android.os.Build object SettingsThemeHelper { private const val IS_EXPRESSIVE_DESIGN_ENABLED = "is_expressive_design_enabled" + private const val RO_BUILD_CHARACTERISTICS = "ro.build.characteristics" private var expressiveThemeState: ExpressiveThemeState = ExpressiveThemeState.UNKNOWN enum class ExpressiveThemeState { @@ -41,6 +42,12 @@ object SettingsThemeHelper { return expressiveThemeState == ExpressiveThemeState.ENABLED } + @JvmStatic + fun isTablet(context: Context): Boolean { + val result = getPropString(context, RO_BUILD_CHARACTERISTICS, "").split(',') + return result.contains("tablet") + } + private fun tryInit(context: Context) { if (expressiveThemeState != ExpressiveThemeState.UNKNOWN) { return @@ -73,4 +80,19 @@ object SettingsThemeHelper { def } } + + private fun getPropString(context: Context, property: String, def: String): String { + return try { + val systemProperties = context.classLoader.loadClass("android.os.SystemProperties") + + val paramTypes = + arrayOf<Class<*>?>(String::class.java, String::class.java) + val get = systemProperties.getMethod("get", *paramTypes) + get.invoke(systemProperties, property, def) as String + } catch (iae: IllegalArgumentException) { + throw iae + } catch (exception: Exception) { + def + } + } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt index 4a7937a3c2ac..e5868d0f1f71 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SearchScaffold.kt @@ -51,12 +51,14 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.lifecycle.ViewModel import androidx.lifecycle.viewmodel.compose.viewModel +import com.android.settingslib.spa.framework.compose.contentDescription import com.android.settingslib.spa.framework.compose.hideKeyboardAction import com.android.settingslib.spa.framework.compose.horizontalValues import com.android.settingslib.spa.framework.theme.SettingsOpacity @@ -175,12 +177,15 @@ private fun SearchBox(query: TextFieldValue, onQueryChange: (TextFieldValue) -> onValueChange = onQueryChange, modifier = Modifier .fillMaxWidth() - .focusRequester(focusRequester), + .focusRequester(focusRequester) + .contentDescription(stringResource(R.string.abc_search_hint)), textStyle = textStyle, placeholder = { Text( text = stringResource(R.string.abc_search_hint), - modifier = Modifier.alpha(SettingsOpacity.Hint), + modifier = Modifier + .alpha(SettingsOpacity.Hint) + .clearAndSetSemantics {}, style = textStyle, ) }, diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SearchScaffoldTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SearchScaffoldTest.kt index 826a0d461c8c..3d73b065751f 100644 --- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SearchScaffoldTest.kt +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/SearchScaffoldTest.kt @@ -130,7 +130,7 @@ class SearchScaffoldTest { ).performClick() } - private fun onSearchHint() = composeTestRule.onNodeWithText( + private fun onSearchHint() = composeTestRule.onNodeWithContentDescription( context.getString(R.string.abc_search_hint) ) diff --git a/packages/SettingsLib/ZeroStatePreference/Android.bp b/packages/SettingsLib/ZeroStatePreference/Android.bp index 4fc00bdbfee0..0949e2c75c55 100644 --- a/packages/SettingsLib/ZeroStatePreference/Android.bp +++ b/packages/SettingsLib/ZeroStatePreference/Android.bp @@ -29,5 +29,6 @@ android_library { min_sdk_version: "28", apex_available: [ "//apex_available:platform", + "com.android.healthfitness", ], } diff --git a/packages/SettingsLib/ZeroStatePreference/res/layout/settingslib_expressive_preference_zerostate.xml b/packages/SettingsLib/ZeroStatePreference/res/layout/settingslib_expressive_preference_zerostate.xml index c0b195cc1f74..ae3f1dde8a3a 100644 --- a/packages/SettingsLib/ZeroStatePreference/res/layout/settingslib_expressive_preference_zerostate.xml +++ b/packages/SettingsLib/ZeroStatePreference/res/layout/settingslib_expressive_preference_zerostate.xml @@ -17,7 +17,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:orientation="vertical"> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 0c71a2195538..bf039adf35e9 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -64,7 +64,7 @@ <string name="connected_via_network_scorer" msgid="7665725527352893558">"מחובר אוטומטית דרך %1$s"</string> <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"מחובר אוטומטית דרך ספק של דירוג רשת"</string> <string name="connected_via_app" msgid="3532267661404276584">"מחוברת באמצעות <xliff:g id="NAME">%1$s</xliff:g>"</string> - <string name="tap_to_sign_up" msgid="5356397741063740395">"יש להקיש כדי להירשם"</string> + <string name="tap_to_sign_up" msgid="5356397741063740395">"יש ללחוץ כדי להירשם"</string> <string name="wifi_connected_no_internet" msgid="5087420713443350646">"אין אינטרנט"</string> <string name="private_dns_broken" msgid="1984159464346556931">"לא ניתן לגשת לשרת DNS הפרטי"</string> <string name="wifi_limited_connection" msgid="1184778285475204682">"חיבור מוגבל"</string> @@ -74,7 +74,7 @@ <string name="osu_opening_provider" msgid="4318105381295178285">"מתבצעת פתיחה של <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string> <string name="osu_connect_failed" msgid="9107873364807159193">"לא ניתן היה להתחבר"</string> <string name="osu_completing_sign_up" msgid="8412636665040390901">"מתבצעת השלמה של ההרשמה…"</string> - <string name="osu_sign_up_failed" msgid="5605453599586001793">"לא ניתן היה להשלים את ההרשמה. יש להקיש כדי לנסות שוב."</string> + <string name="osu_sign_up_failed" msgid="5605453599586001793">"לא ניתן היה להשלים את ההרשמה. יש ללחוץ כדי לנסות שוב."</string> <string name="osu_sign_up_complete" msgid="7640183358878916847">"תהליך ההרשמה הסתיים. בתהליך התחברות…"</string> <string name="speed_label_slow" msgid="6069917670665664161">"איטית"</string> <string name="speed_label_okay" msgid="1253594383880810424">"אישור"</string> @@ -279,7 +279,7 @@ <string name="adb_wireless_no_network_msg" msgid="2365795244718494658">"יש להתחבר לרשת Wi-Fi"</string> <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, ניפוי באגים, פיתוח"</string> <string name="bugreport_in_power" msgid="8664089072534638709">"קיצור דרך לדוח באגים"</string> - <string name="bugreport_in_power_summary" msgid="1885529649381831775">"הצגת לחצן ליצירת דוח על באג בתפריט ההפעלה"</string> + <string name="bugreport_in_power_summary" msgid="1885529649381831775">"הצגת כפתור ליצירת דוח על באג בתפריט ההפעלה"</string> <string name="keep_screen_on" msgid="1187161672348797558">"ללא כניסה למצב שינה"</string> <string name="keep_screen_on_summary" msgid="1510731514101925829">"המסך לעולם לא יהיה במצב שינה במהלך טעינה"</string> <string name="bt_hci_snoop_log" msgid="7291287955649081448">"הפעלת Snoop Log של Bluetooth HCI"</string> @@ -380,8 +380,8 @@ <string name="strict_mode_summary" msgid="1838248687233554654">"המסך יהבהב כשאפליקציות יבצעו פעולות ארוכות ב-thread הראשי"</string> <string name="pointer_location" msgid="7516929526199520173">"מיקום מצביע"</string> <string name="pointer_location_summary" msgid="957120116989798464">"שכבת-על של המסך המציגה את נתוני המגע הנוכחיים"</string> - <string name="show_touches" msgid="8437666942161289025">"הצגת הקשות"</string> - <string name="show_touches_summary" msgid="3692861665994502193">"הצגת משוב ויזואלי להקשות"</string> + <string name="show_touches" msgid="8437666942161289025">"הצגת לחיצות"</string> + <string name="show_touches_summary" msgid="3692861665994502193">"הצגת משוב ויזואלי ללחיצות"</string> <string name="show_key_presses" msgid="6360141722735900214">"הצגת לחיצות המקשים"</string> <string name="show_key_presses_summary" msgid="725387457373015024">"הצגת משוב חזותי עבור לחיצות פיזיות על מקשים"</string> <string name="touchpad_visualizer" msgid="3707916068870825115">"הצגת הקלט של לוח המגע"</string> @@ -440,7 +440,7 @@ <string name="enable_freeform_support" msgid="7599125687603914253">"הפעלת מצב חופשי (חלונות צפים)"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"סיסמת גיבוי שולחן העבודה"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string> - <string name="local_backup_password_summary_change" msgid="1707357670383995567">"יש להקיש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string> + <string name="local_backup_password_summary_change" msgid="1707357670383995567">"יש ללחוץ כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string> <string name="local_backup_password_toast_success" msgid="4891666204428091604">"הוגדרה סיסמת גיבוי חדשה"</string> <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"הסיסמה החדשה והאישור אינם תואמים"</string> <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"הגדרת סיסמת גיבוי נכשלה"</string> @@ -456,8 +456,8 @@ <item msgid="1282170165150762976">"צבעים מותאמים באופן אופטימלי לתוכן דיגיטלי"</item> </string-array> <string name="inactive_apps_title" msgid="5372523625297212320">"אפליקציות בהמתנה"</string> - <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"אפליקציה לא פעילה. יש להקיש כדי להחליף מצב."</string> - <string name="inactive_app_active_summary" msgid="8047630990208722344">"אפליקציה פעילה. יש להקיש כדי להחליף מצב."</string> + <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"אפליקציה לא פעילה. יש ללחוץ כדי להחליף מצב."</string> + <string name="inactive_app_active_summary" msgid="8047630990208722344">"אפליקציה פעילה. יש ללחוץ כדי להחליף מצב."</string> <string name="standby_bucket_summary" msgid="5128193447550429600">"אפליקציה במצב המתנה:<xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="transcode_settings_title" msgid="2581975870429850549">"הגדרות של המרת קידוד למדיה"</string> <string name="transcode_user_control" msgid="6176368544817731314">"ביטול ברירות המחדל של המרת קידוד"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/PreferenceBindings.kt b/packages/SettingsLib/src/com/android/settingslib/PreferenceBindings.kt new file mode 100644 index 000000000000..a64e8cc07b15 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/PreferenceBindings.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:Suppress("ktlint:standard:filename") // remove once we have more bindings + +package com.android.settingslib + +import android.content.Context +import androidx.preference.Preference +import com.android.settingslib.metadata.PreferenceMetadata +import com.android.settingslib.preference.PreferenceBinding + +/** Preference binding for [PrimarySwitchPreference]. */ +interface PrimarySwitchPreferenceBinding : PreferenceBinding { + + override fun createWidget(context: Context): Preference = PrimarySwitchPreference(context) + + override fun bind(preference: Preference, metadata: PreferenceMetadata) { + super.bind(preference, metadata) + (preference as PrimarySwitchPreference).apply { + isChecked = preferenceDataStore!!.getBoolean(key, false) + isSwitchEnabled = isEnabled + } + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 1998d0c6721c..2b8e20ffc71a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -10,6 +10,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.ResolveInfo; import android.content.pm.Signature; import android.content.pm.UserInfo; import android.content.res.ColorStateList; @@ -32,6 +33,7 @@ import android.media.AudioManager; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.TetheringManager; +import android.net.Uri; import android.net.vcn.VcnUtils; import android.net.wifi.WifiInfo; import android.os.BatteryManager; @@ -79,11 +81,14 @@ public class Utils { @VisibleForTesting static final String STORAGE_MANAGER_ENABLED_PROPERTY = "ro.storage_manager.enabled"; + private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; + private static Signature[] sSystemSignature; private static String sPermissionControllerPackageName; private static String sServicesSystemSharedLibPackageName; private static String sSharedSystemSharedLibPackageName; private static String sDefaultWebViewPackageName; + private static String sPackageInstallerPackageName; static final int[] WIFI_PIE = { com.android.internal.R.drawable.ic_wifi_signal_0, @@ -496,9 +501,29 @@ public class Utils { || packageName.equals(sSharedSystemSharedLibPackageName) || packageName.equals(PrintManager.PRINT_SPOOLER_PACKAGE_NAME) || packageName.equals(getDefaultWebViewPackageName(pm)) + || packageName.equals(getPackageInstallerPackageName(pm)) || isDeviceProvisioningPackage(resources, packageName); } + /** Return the package name of the installer */ + private static String getPackageInstallerPackageName(PackageManager pm) { + if (sPackageInstallerPackageName != null) { + return sPackageInstallerPackageName; + } + final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE); + final List<ResolveInfo> matches = + pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); + if (matches.size() == 1) { + final ResolveInfo resolveInfo = matches.get(0); + if (resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { + sPackageInstallerPackageName = resolveInfo.getComponentInfo().packageName; + } + } + return sPackageInstallerPackageName; + } + /** * Returns {@code true} if the supplied package is the device provisioning app. Otherwise, * returns {@code false}. diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java index 5bcdcc09206b..d9e79fa7c9dc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java @@ -52,6 +52,14 @@ import java.util.concurrent.Executors; * BluetoothLeBroadcastAssistant.Callback} to get the result callback. */ public class LocalBluetoothLeBroadcastAssistant implements LocalBluetoothProfile { + /** A derived source state based on {@link BluetoothLeBroadcastReceiveState}. */ + public enum LocalBluetoothLeBroadcastSourceState { + UNKNOWN, + STREAMING, + DECRYPTION_FAILED, + PAUSED, + } + private static final String TAG = "LocalBluetoothLeBroadcastAssistant"; private static final int UNKNOWN_VALUE_PLACEHOLDER = -1; private static final boolean DEBUG = BluetoothUtils.D; @@ -59,6 +67,13 @@ public class LocalBluetoothLeBroadcastAssistant implements LocalBluetoothProfile static final String NAME = "LE_AUDIO_BROADCAST_ASSISTANT"; // Order of this profile in device profiles list private static final int ORDINAL = 1; + // Referring to Broadcast Audio Scan Service 1.0 + // Table 3.9: Broadcast Receive State characteristic format + // 0x00000000: 0b0 = Not synchronized to BIS_index[x] + // 0xFFFFFFFF: Failed to sync to BIG + private static final long BIS_SYNC_NOT_SYNC_TO_BIS = 0x00000000L; + private static final long BIS_SYNC_FAILED_SYNC_TO_BIG = 0xFFFFFFFFL; + private static final String EMPTY_DEVICE_ADDRESS = "00:00:00:00:00:00"; private LocalBluetoothProfileManager mProfileManager; private BluetoothLeBroadcastAssistant mService; @@ -558,4 +573,30 @@ public class LocalBluetoothLeBroadcastAssistant implements LocalBluetoothProfile } } } + + /** Checks the source connection status based on the provided broadcast receive state. */ + public static LocalBluetoothLeBroadcastSourceState getLocalSourceState( + BluetoothLeBroadcastReceiveState state) { + // Source is actively streaming + if (state.getBisSyncState().stream() + .anyMatch( + bitmap -> + (bitmap != BIS_SYNC_NOT_SYNC_TO_BIS + && bitmap != BIS_SYNC_FAILED_SYNC_TO_BIG))) { + return LocalBluetoothLeBroadcastSourceState.STREAMING; + } + // Wrong password is used for the source + if (state.getPaSyncState() == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED + && state.getBigEncryptionState() + == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_BAD_CODE) { + return LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED; + } + // Source in hysteresis mode + if (!state.getSourceDevice().getAddress().equals(EMPTY_DEVICE_ADDRESS)) { + // Referring to Broadcast Audio Scan Service 1.0 + // All zero address means no source on the sink device + return LocalBluetoothLeBroadcastSourceState.PAUSED; + } + return LocalBluetoothLeBroadcastSourceState.UNKNOWN; + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/DndDurationDialogFactory.java index 98c3edba8223..c5fa0aacbda1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/DndDurationDialogFactory.java @@ -44,7 +44,12 @@ import com.android.settingslib.R; import java.util.Arrays; -public class ZenDurationDialog { +/** + * This dialog configures the default behavior that the user prefers when enabling DND. + * Not to be confused with {@link EnableDndDialogFactory}, which is the dialog that will be shown + * when the user enables DND if the "Ask every time" option was selected in this dialog. + */ +public class DndDurationDialogFactory { private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS; @VisibleForTesting protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0]; @@ -72,7 +77,7 @@ public class ZenDurationDialog { @VisibleForTesting protected LayoutInflater mLayoutInflater; - public ZenDurationDialog(Context context) { + public DndDurationDialogFactory(Context context) { mContext = context; } diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableDndDialogFactory.java index c48694cecb4c..f0e7fb851d5f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableDndDialogFactory.java @@ -54,8 +54,15 @@ import java.util.GregorianCalendar; import java.util.Locale; import java.util.Objects; -public class EnableZenModeDialog { - private static final String TAG = "EnableZenModeDialog"; +/** + * When enabling DND, if the user has the setting to "Ask every time" for the duration, we show + * this dialog to allow the user to select for how long they want DND to be enabled this time. + * Not to be confused with {@link DndDurationDialogFactory}, which is the dialog that allows the + * user to configure the default behavior for enabling DND (and in turn may lead to this dialog + * being shown, since it contains the said "Ask every time" option). + */ +public class EnableDndDialogFactory { + private static final String TAG = "EnableDndDialogFactory"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS; @@ -74,7 +81,7 @@ public class EnableZenModeDialog { private static final int MINUTES_MS = 60 * SECONDS_MS; @Nullable - private final ZenModeDialogMetricsLogger mMetricsLogger; + private final EnableDndDialogMetricsLogger mMetricsLogger; @VisibleForTesting protected Uri mForeverId; @@ -101,17 +108,17 @@ public class EnableZenModeDialog { @VisibleForTesting protected LayoutInflater mLayoutInflater; - public EnableZenModeDialog(Context context) { + public EnableDndDialogFactory(Context context) { this(context, 0); } - public EnableZenModeDialog(Context context, int themeResId) { + public EnableDndDialogFactory(Context context, int themeResId) { this(context, themeResId, false /* cancelIsNeutral */, - new ZenModeDialogMetricsLogger(context)); + new EnableDndDialogMetricsLogger(context)); } - public EnableZenModeDialog(Context context, int themeResId, boolean cancelIsNeutral, - ZenModeDialogMetricsLogger metricsLogger) { + public EnableDndDialogFactory(Context context, int themeResId, boolean cancelIsNeutral, + EnableDndDialogMetricsLogger metricsLogger) { mContext = context; mThemeResId = themeResId; mCancelIsNeutral = cancelIsNeutral; diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableDndDialogMetricsLogger.java index 17695e396bef..552bf8d95dcf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableDndDialogMetricsLogger.java @@ -22,12 +22,12 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; /** - * Logs ui events for {@link EnableZenModeDialog}. + * Logs ui events for {@link EnableDndDialogFactory}. */ -public class ZenModeDialogMetricsLogger { +public class EnableDndDialogMetricsLogger { private final Context mContext; - public ZenModeDialogMetricsLogger(Context context) { + public EnableDndDialogMetricsLogger(Context context) { mContext = context; } diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt index 4c4ce2a61851..01bf0c8335d1 100644 --- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt +++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt @@ -27,6 +27,7 @@ import android.provider.Settings import androidx.annotation.IntRange import com.android.internal.util.ConcurrentUtils import com.android.settingslib.bluetooth.BluetoothUtils +import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.bluetooth.onBroadcastStartedOrStopped import com.android.settingslib.bluetooth.onProfileConnectionStateChanged @@ -71,6 +72,12 @@ interface AudioSharingRepository { /** The secondary headset groupId in audio sharing. */ val secondaryGroupId: StateFlow<Int> + /** Primary audio sharing device. */ + val primaryDevice: StateFlow<CachedBluetoothDevice?> + + /** Secondary audio sharing device. */ + val secondaryDevice: StateFlow<CachedBluetoothDevice?> + /** The headset groupId to volume map during audio sharing. */ val volumeMap: StateFlow<GroupIdToVolumes> @@ -144,12 +151,31 @@ class AudioSharingRepositoryImpl( ) override val secondaryGroupId: StateFlow<Int> = - merge( + secondaryDevice + .map { BluetoothUtils.getGroupId(it) } + .onEach { logger.onSecondaryGroupIdChanged(it) } + .flowOn(backgroundCoroutineContext) + .stateIn( + coroutineScope, + SharingStarted.WhileSubscribed(), + BluetoothCsipSetCoordinator.GROUP_ID_INVALID + ) + + override val primaryDevice: StateFlow<CachedBluetoothDevice?> + get() = primaryGroupId.map { getCachedDeviceFromGroupId(it) } + .stateIn( + coroutineScope, + SharingStarted.WhileSubscribed(), + null + ) + + override val secondaryDevice: StateFlow<CachedBluetoothDevice?> + get() = merge( isAudioSharingProfilesReady.flatMapLatest { ready -> if (ready) { btManager.profileManager.leAudioBroadcastAssistantProfile .onSourceConnectedOrRemoved - .map { getSecondaryGroupId() } + .map { getSecondaryDevice() } } else { emptyFlow() } @@ -160,15 +186,14 @@ class AudioSharingRepositoryImpl( profileConnection.bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT } - .map { getSecondaryGroupId() }, - primaryGroupId.map { getSecondaryGroupId() }) - .onStart { emit(getSecondaryGroupId()) } - .onEach { logger.onSecondaryGroupIdChanged(it) } + .map { getSecondaryDevice() }, + primaryGroupId.map { getSecondaryDevice() }) + .onStart { emit(getSecondaryDevice()) } .flowOn(backgroundCoroutineContext) .stateIn( coroutineScope, SharingStarted.WhileSubscribed(), - BluetoothCsipSetCoordinator.GROUP_ID_INVALID + null ) override val volumeMap: StateFlow<GroupIdToVolumes> = @@ -257,10 +282,24 @@ class AudioSharingRepositoryImpl( private fun isBroadcasting(): Boolean = btManager.profileManager.leAudioBroadcastProfile?.isEnabled(null) ?: false - private fun getSecondaryGroupId(): Int = - BluetoothUtils.getGroupId( - BluetoothUtils.getSecondaryDeviceForBroadcast(contentResolver, btManager) - ) + private fun getSecondaryDevice(): CachedBluetoothDevice? = + BluetoothUtils.getSecondaryDeviceForBroadcast(contentResolver, btManager) + + private suspend fun getCachedDeviceFromGroupId(groupId: Int): CachedBluetoothDevice? = + withContext(backgroundCoroutineContext) { + btManager + .profileManager + ?.leAudioBroadcastAssistantProfile + ?.allConnectedDevices + ?.firstNotNullOfOrNull { device -> + val cachedDevice = btManager.cachedDeviceManager.findDevice(device) + if (BluetoothUtils.getGroupId(cachedDevice) == groupId) { + cachedDevice + } else { + null + } + } + } } class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { @@ -269,6 +308,10 @@ class AudioSharingRepositoryEmptyImpl : AudioSharingRepository { MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) override val secondaryGroupId: StateFlow<Int> = MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID) + override val primaryDevice: StateFlow<CachedBluetoothDevice?> + get() = MutableStateFlow(null) + override val secondaryDevice: StateFlow<CachedBluetoothDevice?> + get() = MutableStateFlow(null) override val volumeMap: StateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap()) override suspend fun audioSharingAvailable(): Boolean = false diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt index 8c5a0851cc92..0f25ae208a69 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioSharingRepositoryTest.kt @@ -209,6 +209,21 @@ class AudioSharingRepositoryTest { } @Test + fun primaryDeviceChange_emitValues() { + testScope.runTest { + `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) + + val devices = mutableListOf<CachedBluetoothDevice?>() + underTest.primaryDevice.onEach { devices.add(it) }.launchIn(backgroundScope) + runCurrent() + triggerContentObserverChange() + runCurrent() + + Truth.assertThat(devices).containsExactly(null, cachedDevice2) + } + } + + @Test fun secondaryGroupIdChange_profileNotReady_assistantCallbackNotRegistered() { testScope.runTest { val groupIds = mutableListOf<Int?>() @@ -269,6 +284,29 @@ class AudioSharingRepositoryTest { } @Test + fun secondaryDeviceChange_emitValues() { + testScope.runTest { + `when`(broadcast.isProfileReady).thenReturn(true) + `when`(assistant.isProfileReady).thenReturn(true) + `when`(volumeControl.isProfileReady).thenReturn(true) + val devices = mutableListOf<CachedBluetoothDevice?>() + underTest.secondaryDevice.onEach { devices.add(it) }.launchIn(backgroundScope) + runCurrent() + triggerSourceAdded() + runCurrent() + triggerContentObserverChange() + runCurrent() + + Truth.assertThat(devices) + .containsExactly( + null, + cachedDevice2, + cachedDevice1, + ) + } + } + + @Test fun volumeMapChange_profileReady_emitValues() { testScope.runTest { `when`(broadcast.isProfileReady).thenReturn(true) @@ -363,7 +401,7 @@ class AudioSharingRepositoryTest { TEST_GROUP_ID1 ) `when`(assistant.allConnectedDevices).thenReturn(listOf(device1, device2)) - assistantCallbackCaptor.value.sourceAdded(device1, receiveState) + assistantCallbackCaptor.value.sourceAdded(device1) } private fun triggerSourceRemoved() { @@ -432,11 +470,9 @@ class AudioSharingRepositoryTest { onBroadcastStopped(TEST_REASON, TEST_BROADCAST_ID) } val sourceAdded: - BluetoothLeBroadcastAssistant.Callback.( - sink: BluetoothDevice, state: BluetoothLeBroadcastReceiveState - ) -> Unit = - { sink, state -> - onReceiveStateChanged(sink, TEST_SOURCE_ID, state) + BluetoothLeBroadcastAssistant.Callback.(sink: BluetoothDevice) -> Unit = + { sink -> + onSourceAdded(sink, TEST_SOURCE_ID, TEST_REASON) } val sourceRemoved: BluetoothLeBroadcastAssistant.Callback.(sink: BluetoothDevice) -> Unit = { sink -> diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/DndDurationDialogFactoryTest.java index 19845a04ea18..0b05a4f2dff0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/DndDurationDialogFactoryTest.java @@ -16,6 +16,12 @@ package com.android.settingslib.notification.modes; +import static com.android.settingslib.notification.modes.DndDurationDialogFactory.ALWAYS_ASK_CONDITION_INDEX; +import static com.android.settingslib.notification.modes.DndDurationDialogFactory.COUNTDOWN_CONDITION_INDEX; +import static com.android.settingslib.notification.modes.DndDurationDialogFactory.FOREVER_CONDITION_INDEX; +import static com.android.settingslib.notification.modes.DndDurationDialogFactory.MAX_BUCKET_MINUTES; +import static com.android.settingslib.notification.modes.DndDurationDialogFactory.MIN_BUCKET_MINUTES; + import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; @@ -32,6 +38,8 @@ import android.view.View; import androidx.appcompat.app.AlertDialog; +import com.android.settingslib.notification.modes.DndDurationDialogFactory.ConditionTag; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,8 +47,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) -public class ZenDurationDialogTest { - private ZenDurationDialog mController; +public class DndDurationDialogFactoryTest { + private DndDurationDialogFactory mController; private Context mContext; private LayoutInflater mLayoutInflater; @@ -53,7 +61,7 @@ public class ZenDurationDialogTest { mContentResolver = RuntimeEnvironment.application.getContentResolver(); mLayoutInflater = LayoutInflater.from(mContext); - mController = spy(new ZenDurationDialog(mContext)); + mController = spy(new DndDurationDialogFactory(mContext)); mController.mLayoutInflater = mLayoutInflater; mController.getContentView(); mBuilder = new AlertDialog.Builder(mContext); @@ -65,12 +73,9 @@ public class ZenDurationDialogTest { Settings.Global.ZEN_DURATION_PROMPT); mController.setupDialog(mBuilder); - assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertTrue(mController.getConditionTagAt( - ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); } @Test @@ -79,12 +84,9 @@ public class ZenDurationDialogTest { Settings.Secure.ZEN_DURATION_FOREVER); mController.setupDialog(mBuilder); - assertTrue(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt( - ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); } @Test @@ -92,12 +94,9 @@ public class ZenDurationDialogTest { Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, 45); mController.setupDialog(mBuilder); - assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertTrue(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt( - ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(ALWAYS_ASK_CONDITION_INDEX).rb.isChecked()); } @Test @@ -106,8 +105,7 @@ public class ZenDurationDialogTest { Settings.Secure.ZEN_DURATION_FOREVER); mController.setupDialog(mBuilder); - mController.getConditionTagAt(ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.setChecked( - true); + mController.getConditionTagAt(ALWAYS_ASK_CONDITION_INDEX).rb.setChecked(true); mController.updateZenDuration(Settings.Secure.ZEN_DURATION_FOREVER); assertEquals(Settings.Secure.ZEN_DURATION_PROMPT, Settings.Secure.getInt(mContentResolver, @@ -120,8 +118,7 @@ public class ZenDurationDialogTest { Settings.Secure.ZEN_DURATION_PROMPT); mController.setupDialog(mBuilder); - mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb.setChecked( - true); + mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true); mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT); assertEquals(Settings.Secure.ZEN_DURATION_FOREVER, Settings.Secure.getInt(mContentResolver, @@ -134,8 +131,7 @@ public class ZenDurationDialogTest { Settings.Secure.ZEN_DURATION_PROMPT); mController.setupDialog(mBuilder); - mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb.setChecked( - true); + mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true); mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT); // countdown defaults to 60 minutes: @@ -152,59 +148,50 @@ public class ZenDurationDialogTest { // click time button starts at 60 minutes // - 1 hour to MAX_BUCKET_MINUTES (12 hours), increments by 1 hour // - 0-60 minutes increments by 15 minutes - View view = mController.mZenRadioGroupContent.getChildAt( - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); - ZenDurationDialog.ConditionTag tag = mController.getConditionTagAt( - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + View view = mController.mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX); + ConditionTag tag = mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX); // test incrementing up: - mController.onClickTimeButton(view, tag, true, ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, true, COUNTDOWN_CONDITION_INDEX); assertEquals(120, tag.countdownZenDuration); // goes from 1 hour to 2 hours // try clicking up 50 times - should max out at ZenDurationDialog.MAX_BUCKET_MINUTES for (int i = 0; i < 50; i++) { - mController.onClickTimeButton(view, tag, true, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, true, COUNTDOWN_CONDITION_INDEX); } - assertEquals(ZenDurationDialog.MAX_BUCKET_MINUTES, tag.countdownZenDuration); + assertEquals(MAX_BUCKET_MINUTES, tag.countdownZenDuration); // reset, test incrementing down: mController.mBucketIndex = -1; // reset current bucket index to reset countdownZenDuration tag.countdownZenDuration = 60; // back to default - mController.onClickTimeButton(view, tag, false, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, false, COUNTDOWN_CONDITION_INDEX); assertEquals(45, tag.countdownZenDuration); // goes from 60 minutes to 45 minutes // try clicking down 50 times - should stop at MIN_BUCKET_MINUTES for (int i = 0; i < 50; i++) { - mController.onClickTimeButton(view, tag, false, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, false, COUNTDOWN_CONDITION_INDEX); } - assertEquals(ZenDurationDialog.MIN_BUCKET_MINUTES, tag.countdownZenDuration); + assertEquals(MIN_BUCKET_MINUTES, tag.countdownZenDuration); // reset countdownZenDuration to unbucketed number, should round change to nearest bucket mController.mBucketIndex = -1; tag.countdownZenDuration = 50; - mController.onClickTimeButton(view, tag, false, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, false, COUNTDOWN_CONDITION_INDEX); assertEquals(45, tag.countdownZenDuration); mController.mBucketIndex = -1; tag.countdownZenDuration = 50; - mController.onClickTimeButton(view, tag, true, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, true, COUNTDOWN_CONDITION_INDEX); assertEquals(60, tag.countdownZenDuration); mController.mBucketIndex = -1; tag.countdownZenDuration = 75; - mController.onClickTimeButton(view, tag, false, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, false, COUNTDOWN_CONDITION_INDEX); assertEquals(60, tag.countdownZenDuration); mController.mBucketIndex = -1; tag.countdownZenDuration = 75; - mController.onClickTimeButton(view, tag, true, - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); + mController.onClickTimeButton(view, tag, true, COUNTDOWN_CONDITION_INDEX); assertEquals(120, tag.countdownZenDuration); } @@ -213,12 +200,9 @@ public class ZenDurationDialogTest { Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_FOREVER); mController.setupDialog(mBuilder); - ZenDurationDialog.ConditionTag forever = mController.getConditionTagAt( - ZenDurationDialog.FOREVER_CONDITION_INDEX); - ZenDurationDialog.ConditionTag countdown = mController.getConditionTagAt( - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); - ZenDurationDialog.ConditionTag alwaysAsk = mController.getConditionTagAt( - ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX); + ConditionTag forever = mController.getConditionTagAt(FOREVER_CONDITION_INDEX); + ConditionTag countdown = mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX); + ConditionTag alwaysAsk = mController.getConditionTagAt(ALWAYS_ASK_CONDITION_INDEX); forever.rb.setChecked(true); assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected"); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableDndDialogFactoryTest.java index e397f97e0277..fc9fd8077fd0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableDndDialogFactoryTest.java @@ -16,6 +16,10 @@ package com.android.settingslib.notification.modes; +import static com.android.settingslib.notification.modes.EnableDndDialogFactory.COUNTDOWN_ALARM_CONDITION_INDEX; +import static com.android.settingslib.notification.modes.EnableDndDialogFactory.COUNTDOWN_CONDITION_INDEX; +import static com.android.settingslib.notification.modes.EnableDndDialogFactory.FOREVER_CONDITION_INDEX; + import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; @@ -39,6 +43,8 @@ import android.net.Uri; import android.service.notification.Condition; import android.view.LayoutInflater; +import com.android.settingslib.notification.modes.EnableDndDialogFactory.ConditionTag; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,8 +54,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) -public class EnableZenModeDialogTest { - private EnableZenModeDialog mController; +public class EnableDndDialogFactoryTest { + private EnableDndDialogFactory mController; @Mock private Context mContext; @@ -74,7 +80,7 @@ public class EnableZenModeDialogTest { when(mFragment.getContext()).thenReturn(mShadowContext); mLayoutInflater = LayoutInflater.from(mShadowContext); - mController = spy(new EnableZenModeDialog(mContext)); + mController = spy(new EnableDndDialogFactory(mContext)); mController.mContext = mContext; mController.mLayoutInflater = mLayoutInflater; mController.mForeverId = Condition.newId(mContext).appendPath("forever").build(); @@ -101,36 +107,29 @@ public class EnableZenModeDialogTest { Uri countdown = Condition.newId(mContext).appendPath("countdown").build(); mCountdownCondition = new Condition(countdown, "countdown", "", "", 0, 0, 0); mController.bind(mCountdownCondition, - mController.mZenRadioGroupContent.getChildAt( - EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX), - EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX); + mController.mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX), + COUNTDOWN_CONDITION_INDEX); mController.bind(mAlarmCondition, mController.mZenRadioGroupContent.getChildAt( - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX), - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX); + COUNTDOWN_ALARM_CONDITION_INDEX), + COUNTDOWN_ALARM_CONDITION_INDEX); } @Test public void testForeverChecked() { mController.bindConditions(mController.forever()); - assertTrue(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt( - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); } @Test public void testNoneChecked() { mController.bindConditions(null); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt( - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); } @Test @@ -139,12 +138,9 @@ public class EnableZenModeDialogTest { doReturn(true).when(mController).isAlarm(mAlarmCondition); mController.bindConditions(mAlarmCondition); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertTrue(mController.getConditionTagAt( - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); } @Test @@ -153,12 +149,9 @@ public class EnableZenModeDialogTest { doReturn(true).when(mController).isCountdown(mCountdownCondition); mController.bindConditions(mCountdownCondition); - assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb - .isChecked()); - assertTrue(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb - .isChecked()); - assertFalse(mController.getConditionTagAt( - EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(FOREVER_CONDITION_INDEX).rb.isChecked()); + assertTrue(mController.getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.isChecked()); + assertFalse(mController.getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); } @Test @@ -198,12 +191,12 @@ public class EnableZenModeDialogTest { @Test public void testAccessibility() { mController.bindConditions(null); - EnableZenModeDialog.ConditionTag forever = mController.getConditionTagAt( - ZenDurationDialog.FOREVER_CONDITION_INDEX); - EnableZenModeDialog.ConditionTag countdown = mController.getConditionTagAt( - ZenDurationDialog.COUNTDOWN_CONDITION_INDEX); - EnableZenModeDialog.ConditionTag alwaysAsk = mController.getConditionTagAt( - ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX); + ConditionTag forever = mController.getConditionTagAt( + DndDurationDialogFactory.FOREVER_CONDITION_INDEX); + ConditionTag countdown = mController.getConditionTagAt( + DndDurationDialogFactory.COUNTDOWN_CONDITION_INDEX); + ConditionTag alwaysAsk = mController.getConditionTagAt( + DndDurationDialogFactory.ALWAYS_ASK_CONDITION_INDEX); forever.rb.setChecked(true); assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected"); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java index 3f3e1b280850..c8738ae0c8eb 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java @@ -251,8 +251,8 @@ public class IllustrationPreferenceTest { mPreference.setMaxHeight(maxHeight); mPreference.onBindViewHolder(mViewHolder); - assertThat(mBackgroundView.getMaxHeight()).isEqualTo(restrictedHeight); - assertThat(mAnimationView.getMaxHeight()).isEqualTo(restrictedHeight); + assertThat(mBackgroundView.getMaxHeight()).isEqualTo(maxHeight); + assertThat(mAnimationView.getMaxHeight()).isEqualTo(maxHeight); } @Test diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 9b75a47d92ac..c47bf628002d 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -385,6 +385,9 @@ public class SettingsProvider extends ContentProvider { private static final Set<String> sDeviceConfigAllowlistedNamespaces = new ArraySet<>(); + // TODO(b/388901162): Remove this when the same constant is exposed as an API in DeviceConfig. + private static final String DEVICE_CONFIG_OVERRIDES_NAMESPACE = "device_config_overrides"; + // We have to call in the user manager with no lock held, private volatile UserManager mUserManager; @@ -2480,12 +2483,21 @@ public class SettingsProvider extends ContentProvider { for (String flag : flags) { boolean namespaceAllowed = false; if (isRestrictedShell) { - int delimiterIndex = flag.indexOf("/"); - String flagNamespace; - if (delimiterIndex != -1) { - flagNamespace = flag.substring(0, delimiterIndex); - } else { - flagNamespace = flag; + String flagNamespace = getFlagNamespace(flag); + // If the namespace indicates this is a flag override, then the actual + // namespace and flag name should be used for the allowlist verification. + if (DEVICE_CONFIG_OVERRIDES_NAMESPACE.equals(flagNamespace)) { + // Override flags are in the following form: + // device_config_overrides/namespace:flagName + int slashIndex = flag.indexOf("/"); + int colonIndex = flag.indexOf(":", slashIndex); + if (slashIndex != -1 && colonIndex != -1 && (slashIndex + 1) < flag.length() + && (colonIndex + 1) < flag.length()) { + flagNamespace = flag.substring(slashIndex + 1, colonIndex); + StringBuilder flagBuilder = new StringBuilder(flagNamespace); + flagBuilder.append("/").append(flag.substring(colonIndex + 1)); + flag = flagBuilder.toString(); + } } if (allowlistedDeviceConfigNamespaces.contains(flagNamespace)) { namespaceAllowed = true; @@ -2512,6 +2524,23 @@ public class SettingsProvider extends ContentProvider { } } + /** + * Returns the namespace for the provided {@code flag}. + * <p> + * Flags are expected to be in the form namespace/flagName; if the '/' delimiter does + * not exist, then the provided flag is returned as the namespace. + */ + private static String getFlagNamespace(String flag) { + int delimiterIndex = flag.indexOf("/"); + String flagNamespace; + if (delimiterIndex != -1) { + flagNamespace = flag.substring(0, delimiterIndex); + } else { + flagNamespace = flag; + } + return flagNamespace; + } + // The check is added mainly for auto devices. On auto devices, it is possible that // multiple users are visible simultaneously using visible background users. // In such cases, it is desired that Non-current user (ex. visible background users) can diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml index 816fe3b432bc..be81c2ed3792 100644 --- a/packages/Shell/res/values-iw/strings.xml +++ b/packages/Shell/res/values-iw/strings.xml @@ -24,10 +24,10 @@ <string name="bugreport_updating_wait" msgid="3322151947853929470">"רק רגע…"</string> <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"הדוח על הבאג יופיע בטלפון בקרוב"</string> <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"יש להקיש כדי לשתף את הדוח על הבאג"</string> - <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"יש להקיש כדי לשתף את הדוח על הבאג"</string> + <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"יש ללחוץ כדי לשתף את הדוח על הבאג"</string> <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"אפשר להחליק ימינה כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string> - <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"יש להקיש כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string> - <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"יש להקיש כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"יש ללחוץ כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"יש ללחוץ כדי לשתף את הדוח על הבאג ללא צילום מסך, או להמתין להשלמת צילום המסך"</string> <string name="bugreport_confirm" msgid="5917407234515812495">"דוחות על באגים כוללים נתונים מקובצי היומן השונים במערכת, שעשויים לכלול נתונים הנחשבים רגישים (כגון שימוש באפליקציות ונתוני מיקום). כדאי לשתף דוחות על באגים רק עם אפליקציות ואנשים מהימנים."</string> <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"אין צורך להציג זאת שוב"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"דוחות על באגים"</string> diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index c6cc9a975191..33e9919f06eb 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -24,6 +24,7 @@ bhinegardner@google.com bhnm@google.com brycelee@google.com brzezinski@google.com +burakov@google.com caitlinshk@google.com cameronyee@google.com chandruis@google.com @@ -39,6 +40,7 @@ florenceyang@google.com gallmann@google.com graciecheng@google.com gwasserman@google.com +helencheuk@google.com hwwang@google.com hyunyoungs@google.com ikateryna@google.com diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml index 3f8671c83ccc..db733fc33a21 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml +++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml @@ -23,8 +23,8 @@ <string name="accessibility_menu_description" msgid="4458354794093858297">"תפריט הנגישות הוא תפריט גדול שמופיע במסך ומאפשר לשלוט במכשיר. אפשר לנעול את המכשיר, לשלוט בעוצמת הקול ובבהירות, לצלם צילומי מסך ועוד."</string> <string name="accessibility_menu_summary" msgid="340071398148208130">"שליטה במכשיר באמצעות התפריט הגדול"</string> <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"הגדרות של תפריט נגישות"</string> - <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"לחצנים גדולים"</string> - <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"הגדלת הלחצנים של תפריט הנגישות"</string> + <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"כפתורים גדולים"</string> + <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"הגדלת הכפתורים של תפריט הנגישות"</string> <string name="pref_help_title" msgid="6871558837025010641">"עזרה"</string> <string name="brightness_percentage_label" msgid="7391554573977867369">"בהירות %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string> <string name="music_volume_percentage_label" msgid="398635599662604706">"עוצמת הקול של המוזיקה %% <xliff:g id="PERCENTAGE">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index b33421d5d4ca..9531bc38e797 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -493,6 +493,14 @@ flag { } flag { + name: "status_bar_no_hun_behavior" + namespace: "systemui" + description: "When there's a HUN, don't show the HUN text or icon in the status bar. Instead, " + "continue showing the usual status bar." + bug: "385740230" +} + +flag { name: "promote_notifications_automatically" namespace: "systemui" description: "Flag to automatically turn certain notifications into promoted notifications so " @@ -617,13 +625,6 @@ flag { } flag { - name: "status_bar_connected_displays" - namespace: "lse_desktop_experience" - description: "Shows the status bar on connected displays" - bug: "379264862" -} - -flag { name: "status_bar_switch_to_spn_from_data_spn" namespace: "systemui" description: "Fix usage of the SPN broadcast extras" @@ -1919,3 +1920,23 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "stabilize_heads_up_group" + namespace: "systemui" + description: "Stabilize heads up groups in VisualStabilityCoordinator" + bug: "381864715" + metadata { + purpose: PURPOSE_BUGFIX + } +} + +flag { + name: "magnetic_notification_horizontal_swipe" + namespace: "systemui" + description: "Add support for magnetic behavior on horizontal notification swipes." + bug: "390179908" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java index 8a57e8cbbb20..f36f0306d82b 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java @@ -27,6 +27,7 @@ import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_EXIT_TRAN import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static com.android.internal.util.Preconditions.checkArgument; +import static com.android.wm.shell.shared.TransitionUtil.FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY; import static com.android.wm.shell.shared.TransitionUtil.isClosingMode; import static com.android.wm.shell.shared.TransitionUtil.isClosingType; import static com.android.wm.shell.shared.TransitionUtil.isOpeningMode; @@ -270,7 +271,8 @@ public abstract class RemoteAnimationRunnerCompat extends IRemoteAnimationRunner // skip changes that we didn't wrap if (!leashMap.containsKey(change.getLeash())) continue; // Only make the update if we are closing Desktop tasks. - if (change.getTaskInfo() != null && change.getTaskInfo().isFreeform() + if (change.getTaskInfo() != null && (change.getTaskInfo().isFreeform() + || change.hasFlags(FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY)) && isClosingMode(change.getMode())) { startTransaction.setAlpha(leashMap.get(launcherChange.getLeash()), 0f); return; diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt index 439968590dad..d43b596b32f1 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerContent.kt @@ -87,10 +87,10 @@ import androidx.compose.ui.unit.times import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.PlatformButton import com.android.compose.animation.Easings +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.MutableSceneTransitionLayoutState import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.transitions import com.android.compose.windowsizeclass.LocalWindowSizeClass @@ -515,7 +515,7 @@ private fun FoldAware( } @Composable -private fun SceneScope.FoldableScene( +private fun ContentScope.FoldableScene( aboveFold: @Composable BoxScope.() -> Unit, belowFold: @Composable BoxScope.() -> Unit, isSplit: Boolean, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt index 55b42931b1fa..fad8ae7e3ba2 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt @@ -24,8 +24,8 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.bouncer.ui.BouncerDialogFactory @@ -73,7 +73,7 @@ constructor( } @Composable - override fun SceneScope.Content(modifier: Modifier) = + override fun ContentScope.Content(modifier: Modifier) = BouncerScene( viewModel = rememberViewModel("BouncerScene") { contentViewModelFactory.create() }, dialogFactory = dialogFactory, @@ -82,7 +82,7 @@ constructor( } @Composable -private fun SceneScope.BouncerScene( +private fun ContentScope.BouncerScene( viewModel: BouncerSceneContentViewModel, dialogFactory: BouncerDialogFactory, modifier: Modifier = Modifier, @@ -96,8 +96,8 @@ private fun SceneScope.BouncerScene( drawRect(color = backgroundColor) } - // Separate the bouncer content into a reusable composable that doesn't have any SceneScope - // dependencies + // Separate the bouncer content into a reusable composable that doesn't have any + // ContentScope dependencies BouncerContent( viewModel, dialogFactory, 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 a2a91fcd5d52..9b5ff7f9e7e8 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 @@ -33,13 +33,13 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.android.compose.animation.scene.ContentKey +import com.android.compose.animation.scene.ContentScope 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.LowestZIndexContentPicker import com.android.compose.animation.scene.MutableSceneTransitionLayoutState import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.Swipe import com.android.compose.animation.scene.observableTransitionState @@ -229,7 +229,7 @@ fun CommunalContainer( /** Scene containing the glanceable hub UI. */ @Composable -fun SceneScope.CommunalScene( +fun ContentScope.CommunalScene( backgroundType: CommunalBackgroundType, colors: CommunalColors, content: CommunalContent, 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 index 0a0003ee9a8a..fea34921b853 100644 --- 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 @@ -31,7 +31,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntRect import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection @@ -65,7 +65,7 @@ constructor( ) { @Composable - fun SceneScope.Content(modifier: Modifier = Modifier) { + fun ContentScope.Content(modifier: Modifier = Modifier) { CommunalTouchableSurface(viewModel = viewModel, modifier = modifier) { Layout( modifier = Modifier.fillMaxSize(), @@ -81,7 +81,7 @@ constructor( dialogFactory = dialogFactory, widgetSection = widgetSection, modifier = Modifier.element(Communal.Elements.Grid), - sceneScope = this@Content, + contentScope = this@Content, ) } if (communalSettingsInteractor.isV2FlagEnabled()) { @@ -193,6 +193,7 @@ constructor( companion object { private val screensaverButtonSize: Dp = 64.dp private val screensaverButtonPadding: Dp = 24.dp + // TODO(b/382739998): Remove these hardcoded values once lock icon size and bottom area // position are sorted. private val lockIconSize: Dp = 54.dp 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 068df8e31ed0..70a74f064563 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 @@ -171,7 +171,7 @@ import androidx.compose.ui.zIndex import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.window.layout.WindowMetricsCalculator import com.android.compose.animation.Easings.Emphasized -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.thenIf import com.android.compose.ui.graphics.painter.rememberDrawablePainter import com.android.internal.R.dimen.system_app_widget_background_radius @@ -217,7 +217,7 @@ fun CommunalHub( widgetConfigurator: WidgetConfigurator? = null, onOpenWidgetPicker: (() -> Unit)? = null, onEditDone: (() -> Unit)? = null, - sceneScope: SceneScope? = null, + contentScope: ContentScope? = null, ) { val communalContent by viewModel.communalContent.collectAsStateWithLifecycle(initialValue = emptyList()) @@ -437,7 +437,7 @@ fun CommunalHub( widgetConfigurator = widgetConfigurator, interactionHandler = interactionHandler, widgetSection = widgetSection, - sceneScope = sceneScope, + contentScope = contentScope, ) } } @@ -827,7 +827,7 @@ private fun BoxScope.CommunalHubLazyGrid( widgetConfigurator: WidgetConfigurator?, interactionHandler: RemoteViews.InteractionHandler?, widgetSection: CommunalAppWidgetSection, - sceneScope: SceneScope?, + contentScope: ContentScope?, ) { var gridModifier = Modifier.align(Alignment.TopStart).onGloballyPositioned { setGridCoordinates(it) } @@ -1009,7 +1009,7 @@ private fun BoxScope.CommunalHubLazyGrid( interactionHandler = interactionHandler, widgetSection = widgetSection, resizeableItemFrameViewModel = resizeableItemFrameViewModel, - sceneScope = sceneScope, + contentScope = contentScope, ) } } @@ -1261,7 +1261,7 @@ private fun CommunalContent( interactionHandler: RemoteViews.InteractionHandler?, widgetSection: CommunalAppWidgetSection, resizeableItemFrameViewModel: ResizeableItemFrameViewModel, - sceneScope: SceneScope? = null, + contentScope: ContentScope? = null, ) { when (model) { is CommunalContentModel.WidgetContent.Widget -> @@ -1285,7 +1285,7 @@ private fun CommunalContent( is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, modifier) is CommunalContentModel.Smartspace -> SmartspaceContent(interactionHandler, model, modifier) is CommunalContentModel.Tutorial -> TutorialContent(modifier) - is CommunalContentModel.Umo -> Umo(viewModel, sceneScope, modifier) + is CommunalContentModel.Umo -> Umo(viewModel, contentScope, modifier) is CommunalContentModel.Spacer -> Box(Modifier.fillMaxSize()) } } @@ -1451,7 +1451,6 @@ private fun WidgetContent( } else { Modifier } - Box( modifier = modifier @@ -1539,7 +1538,10 @@ private fun WidgetContent( with(widgetSection) { Widget( isFocusable = isFocusable, - openWidgetEditor = { viewModel.onOpenWidgetEditor() }, + openWidgetEditor = { + viewModel.setSelectedKey(model.key) + viewModel.onOpenWidgetEditor() + }, model = model, size = size, modifier = Modifier.fillMaxSize().allowGestures(allowed = !viewModel.isEditMode), @@ -1701,11 +1703,11 @@ private fun TutorialContent(modifier: Modifier = Modifier) { @Composable private fun Umo( viewModel: BaseCommunalViewModel, - sceneScope: SceneScope?, + contentScope: ContentScope?, modifier: Modifier = Modifier, ) { - if (SceneContainerFlag.isEnabled && sceneScope != null) { - sceneScope.MediaCarousel( + if (SceneContainerFlag.isEnabled && contentScope != null) { + contentScope.MediaCarousel( modifier = modifier.fillMaxSize(), isVisible = true, mediaHost = viewModel.mediaHost, @@ -1788,6 +1790,7 @@ fun AccessibilityContainer(viewModel: BaseCommunalViewModel, content: @Composabl CustomAccessibilityAction( context.getString(R.string.accessibility_action_label_edit_widgets) ) { + viewModel.setSelectedKey(null) viewModel.onOpenWidgetEditor() true }, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt index 88b651019c4a..143fbe4de550 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.communal.shared.model.CommunalBackgroundType @@ -55,7 +55,7 @@ constructor( } @Composable - override fun SceneScope.Content(modifier: Modifier) { + override fun ContentScope.Content(modifier: Modifier) { val backgroundType by contentViewModel.communalBackground.collectAsStateWithLifecycle( initialValue = CommunalBackgroundType.ANIMATED diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/AmbientStatusBarSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/AmbientStatusBarSection.kt index 3b335fa3141e..1b0ddcb13ee2 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/AmbientStatusBarSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/AmbientStatusBarSection.kt @@ -22,7 +22,7 @@ import android.widget.FrameLayout import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.ambient.statusbar.dagger.AmbientStatusBarComponent import com.android.systemui.ambient.statusbar.ui.AmbientStatusBarView import com.android.systemui.communal.ui.compose.Communal @@ -31,11 +31,9 @@ import javax.inject.Inject class AmbientStatusBarSection @Inject -constructor( - private val factory: AmbientStatusBarComponent.Factory, -) { +constructor(private val factory: AmbientStatusBarComponent.Factory) { @Composable - fun SceneScope.AmbientStatusBar(modifier: Modifier = Modifier) { + fun ContentScope.AmbientStatusBar(modifier: Modifier = Modifier) { AndroidView( factory = { context -> (LayoutInflater.from(context) @@ -49,7 +47,7 @@ constructor( factory.create(this).getController().apply { init() } } }, - modifier = modifier.element(Communal.Elements.StatusBar) + modifier = modifier.element(Communal.Elements.StatusBar), ) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/dream/ui/composable/DreamScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/dream/ui/composable/DreamScene.kt index f4374c6c9487..6cd0c5dfd15c 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/dream/ui/composable/DreamScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/dream/ui/composable/DreamScene.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.systemui.dagger.SysUISingleton @@ -54,7 +54,7 @@ constructor(private val actionsViewModelFactory: DreamUserActionsViewModel.Facto } @Composable - override fun SceneScope.Content(modifier: Modifier) { + override fun ContentScope.Content(modifier: Modifier) { Box(modifier = modifier.fillMaxSize()) { // Render a sleep emoji to make the scene appear visible. Text( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt index 5c5514aec03e..7b2f9dc76158 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalView import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.ui.composable.blueprint.ComposableLockscreenSceneBlueprint @@ -50,7 +50,7 @@ class LockscreenContent( } @Composable - fun SceneScope.Content(modifier: Modifier = Modifier) { + fun ContentScope.Content(modifier: Modifier = Modifier) { val viewModel = rememberViewModel("LockscreenContent-viewModel") { viewModelFactory.create() } val notificationLockscreenScrimViewModel = diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt index c7c29f9fdb7c..5e61af634bbc 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt @@ -19,7 +19,7 @@ package com.android.systemui.keyguard.ui.composable import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateContentFloatAsState @@ -54,18 +54,13 @@ constructor( } @Composable - override fun SceneScope.Content( - modifier: Modifier, - ) { - LockscreenScene( - lockscreenContent = lockscreenContent, - modifier = modifier, - ) + override fun ContentScope.Content(modifier: Modifier) { + LockscreenScene(lockscreenContent = lockscreenContent, modifier = modifier) } } @Composable -private fun SceneScope.LockscreenScene( +private fun ContentScope.LockscreenScene( lockscreenContent: Lazy<LockscreenContent>, modifier: Modifier = Modifier, ) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt index adad4468b751..c365ec590a5f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt @@ -23,7 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.keyguard.ui.composable.LockscreenLongPress import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel import dagger.Binds @@ -37,14 +37,8 @@ class CommunalBlueprint @Inject constructor() : ComposableLockscreenSceneBluepri override val id: String = "communal" @Composable - override fun SceneScope.Content( - viewModel: LockscreenContentViewModel, - modifier: Modifier, - ) { - LockscreenLongPress( - viewModel = viewModel.touchHandling, - modifier = modifier, - ) { _ -> + override fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) { + LockscreenLongPress(viewModel = viewModel.touchHandling, modifier = modifier) { _ -> Box(modifier.background(Color.Black)) { Text( text = "TODO(b/316211368): communal blueprint", diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ComposableLockscreenSceneBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ComposableLockscreenSceneBlueprint.kt index df36d0774f11..cfafb6214c45 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ComposableLockscreenSceneBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ComposableLockscreenSceneBlueprint.kt @@ -18,16 +18,12 @@ package com.android.systemui.keyguard.ui.composable.blueprint import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.keyguard.shared.model.LockscreenSceneBlueprint import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel /** Defines interface for classes that can render the content for a specific blueprint/layout. */ interface ComposableLockscreenSceneBlueprint : LockscreenSceneBlueprint { /** Renders the content of this blueprint. */ - @Composable - fun SceneScope.Content( - viewModel: LockscreenContentViewModel, - modifier: Modifier, - ) + @Composable fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt index 9643f192e066..c55a3fdfc6c0 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntRect import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.keyguard.ui.composable.LockscreenLongPress @@ -68,7 +68,7 @@ constructor( override val id: String = "default" @Composable - override fun SceneScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) { + override fun ContentScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) { val isUdfpsVisible = viewModel.isUdfpsVisible val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle() val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle() diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt index af9a195c4575..99a7633e3cd3 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/AmbientIndicationSection.kt @@ -18,9 +18,9 @@ package com.android.systemui.keyguard.ui.composable.section import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope /** Defines interface for classes that can render the ambient indication area. */ interface AmbientIndicationSection { - @Composable fun SceneScope.AmbientIndication(modifier: Modifier) + @Composable fun ContentScope.AmbientIndication(modifier: Modifier) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt index 5e9ade163ac2..52ccab3b4d1e 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt @@ -30,8 +30,8 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.DpSize import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.res.ResourcesCompat +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey -import com.android.compose.animation.scene.SceneScope import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder @@ -61,7 +61,7 @@ constructor( * shortcut is placed along the edges of the display. */ @Composable - fun SceneScope.Shortcut( + fun ContentScope.Shortcut( isStart: Boolean, applyPadding: Boolean, modifier: Modifier = Modifier, @@ -89,7 +89,7 @@ constructor( } @Composable - fun SceneScope.IndicationArea(modifier: Modifier = Modifier) { + fun ContentScope.IndicationArea(modifier: Modifier = Modifier) { Element(key = IndicationAreaElementKey, modifier = modifier.indicationAreaPadding()) { content { IndicationArea( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt index fb01e7039edd..34c0bcaca997 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.contains import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.customization.R import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey @@ -54,7 +54,7 @@ constructor( private val aodBurnInViewModel: AodBurnInViewModel, ) { @Composable - fun SceneScope.SmallClock( + fun ContentScope.SmallClock( burnInParams: BurnInParameters, onTopChanged: (top: Float?) -> Unit, modifier: Modifier = Modifier, @@ -87,7 +87,7 @@ constructor( } @Composable - fun SceneScope.LargeClock(burnInParams: BurnInParameters, modifier: Modifier = Modifier) { + fun ContentScope.LargeClock(burnInParams: BurnInParameters, modifier: Modifier = Modifier) { val currentClock by viewModel.currentClock.collectAsStateWithLifecycle() if (currentClock?.largeClock?.view == null) { return 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 597cbf24729b..4795e7cef87c 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 @@ -28,8 +28,8 @@ import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntRect import androidx.compose.ui.viewinterop.AndroidView +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey -import com.android.compose.animation.scene.SceneScope import com.android.systemui.biometrics.AuthController import com.android.systemui.customization.R as customR import com.android.systemui.dagger.qualifiers.Application @@ -66,7 +66,7 @@ constructor( @LongPressTouchLog private val logBuffer: LogBuffer, ) { @Composable - fun SceneScope.LockIcon(overrideColor: Color? = null, modifier: Modifier = Modifier) { + fun ContentScope.LockIcon(overrideColor: Color? = null, modifier: Modifier = Modifier) { val context = LocalContext.current AndroidView( 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 4a9f44b74099..0ff567bf90ad 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 @@ -23,7 +23,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope 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 @@ -42,7 +42,7 @@ constructor( ) { @Composable - fun SceneScope.KeyguardMediaCarousel( + fun ContentScope.KeyguardMediaCarousel( isShadeLayoutWide: Boolean, modifier: Modifier = Modifier, ) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt index 0344ab8e0196..2bc392d386bf 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt @@ -34,7 +34,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.thenIf import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.SysUISingleton @@ -148,7 +148,7 @@ constructor( } @Composable - fun SceneScope.HeadsUpNotifications() { + fun ContentScope.HeadsUpNotifications() { SnoozeableHeadsUpNotificationSpace( stackScrollView = stackScrollView.get(), viewModel = rememberViewModel("HeadsUpNotifications") { viewModelFactory.create() }, @@ -160,7 +160,7 @@ constructor( * adjustment */ @Composable - fun SceneScope.Notifications( + fun ContentScope.Notifications( areNotificationsVisible: Boolean, isShadeLayoutWide: Boolean, burnInParams: BurnInParameters?, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt index 1cee4d67df3b..c3ba7ab2fd19 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SmartSpaceSection.kt @@ -35,7 +35,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys @@ -57,7 +57,7 @@ constructor( private val aodBurnInViewModel: AodBurnInViewModel, ) { @Composable - fun SceneScope.SmartSpace( + fun ContentScope.SmartSpace( burnInParams: BurnInParameters, onTopChanged: (top: Float?) -> Unit, smartSpacePaddingTop: (Resources) -> Int, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt index 0d8a47019a08..172c3f5a1135 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/StatusBarSection.kt @@ -26,7 +26,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.viewinterop.AndroidView -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.height import com.android.keyguard.dagger.KeyguardStatusBarViewComponent import com.android.systemui.common.ui.compose.windowinsets.LocalDisplayCutout @@ -45,9 +45,10 @@ constructor( private val notificationPanelView: Lazy<NotificationPanelView>, ) { @Composable - fun SceneScope.StatusBar(modifier: Modifier = Modifier) { + fun ContentScope.StatusBar(modifier: Modifier = Modifier) { val context = LocalContext.current val viewDisplayCutout = LocalDisplayCutout.current.viewDisplayCutoutKeyguardStatusBarView + @SuppressLint("InflateParams") val view = remember(context) { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt index 73c4fab7b646..6250da379402 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/WeatherClockSection.kt @@ -30,9 +30,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.viewinterop.AndroidView +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey -import com.android.compose.animation.scene.SceneScope -import com.android.compose.modifiers.padding import com.android.systemui.customization.R as customR import com.android.systemui.keyguard.ui.composable.blueprint.WeatherClockElementKeys import com.android.systemui.keyguard.ui.composable.modifier.burnInAware @@ -50,15 +49,10 @@ constructor( private val aodBurnInViewModel: AodBurnInViewModel, ) { @Composable - fun SceneScope.Time( - clock: ClockController, - burnInParams: BurnInParameters, - ) { + fun ContentScope.Time(clock: ClockController, burnInParams: BurnInParameters) { Row( modifier = - Modifier.padding( - horizontal = dimensionResource(customR.dimen.clock_padding_start) - ) + Modifier.padding(horizontal = dimensionResource(customR.dimen.clock_padding_start)) .burnInAware(aodBurnInViewModel, burnInParams, isClock = true) ) { WeatherElement( @@ -70,10 +64,7 @@ constructor( } @Composable - private fun SceneScope.Date( - clock: ClockController, - modifier: Modifier = Modifier, - ) { + private fun ContentScope.Date(clock: ClockController, modifier: Modifier = Modifier) { WeatherElement( weatherClockElementViewId = customR.id.weather_clock_date, clock = clock, @@ -83,10 +74,7 @@ constructor( } @Composable - private fun SceneScope.Weather( - clock: ClockController, - modifier: Modifier = Modifier, - ) { + private fun ContentScope.Weather(clock: ClockController, modifier: Modifier = Modifier) { WeatherElement( weatherClockElementViewId = customR.id.weather_clock_weather_icon, clock = clock, @@ -96,10 +84,7 @@ constructor( } @Composable - private fun SceneScope.DndAlarmStatus( - clock: ClockController, - modifier: Modifier = Modifier, - ) { + private fun ContentScope.DndAlarmStatus(clock: ClockController, modifier: Modifier = Modifier) { WeatherElement( weatherClockElementViewId = customR.id.weather_clock_alarm_dnd, clock = clock, @@ -109,10 +94,7 @@ constructor( } @Composable - private fun SceneScope.Temperature( - clock: ClockController, - modifier: Modifier = Modifier, - ) { + private fun ContentScope.Temperature(clock: ClockController, modifier: Modifier = Modifier) { WeatherElement( weatherClockElementViewId = customR.id.weather_clock_temperature, clock = clock, @@ -122,7 +104,7 @@ constructor( } @Composable - private fun SceneScope.WeatherElement( + private fun ContentScope.WeatherElement( weatherClockElementViewId: Int, clock: ClockController, elementKey: ElementKey, @@ -144,32 +126,28 @@ constructor( } }, update = {}, - modifier = modifier + modifier = modifier, ) } } } @Composable - fun SceneScope.LargeClockSectionBelowSmartspace( + fun ContentScope.LargeClockSectionBelowSmartspace( burnInParams: BurnInParameters, clock: ClockController, ) { Row( modifier = Modifier.height(IntrinsicSize.Max) - .padding( - horizontal = dimensionResource(customR.dimen.clock_padding_start) - ) + .padding(horizontal = dimensionResource(customR.dimen.clock_padding_start)) .burnInAware(aodBurnInViewModel, burnInParams, isClock = true) ) { Date(clock = clock, modifier = Modifier.wrapContentSize()) Box( modifier = Modifier.fillMaxSize() - .padding( - start = dimensionResource(customR.dimen.clock_padding_start) - ) + .padding(start = dimensionResource(customR.dimen.clock_padding_start)) ) { Weather(clock = clock, modifier = Modifier.align(Alignment.TopStart)) Temperature(clock = clock, modifier = Modifier.align(Alignment.BottomEnd)) 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 b5d78398028d..f5de7dca6d9d 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 @@ -31,8 +31,8 @@ import androidx.compose.ui.layout.layout import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.viewinterop.AndroidView +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.MovableElementKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.media.controls.ui.composable.MediaCarouselStateLoader.stateForMediaCarouselContent import com.android.systemui.media.controls.ui.controller.MediaCarouselController @@ -52,7 +52,7 @@ object MediaCarousel { } @Composable -fun SceneScope.MediaCarousel( +fun ContentScope.MediaCarousel( isVisible: Boolean, mediaHost: MediaHost, modifier: Modifier = Modifier, @@ -136,6 +136,6 @@ private fun ViewGroup.setView(view: View) { } @Composable -fun SceneScope.isLandscape(): Boolean { +fun ContentScope.isLandscape(): Boolean { return LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Compact } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt index bad74052b669..525284207744 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaCarouselStateLoader.kt @@ -17,8 +17,8 @@ package com.android.systemui.media.controls.ui.composable import com.android.compose.animation.scene.ContentKey +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.content.state.TransitionState import com.android.systemui.media.controls.ui.controller.MediaCarouselController import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager @@ -50,6 +50,7 @@ object MediaCarouselStateLoader { if (isSplitShade) MediaHierarchyManager.LOCATION_QS else MediaHierarchyManager.LOCATION_QQS } + Scenes.Lockscreen -> MediaHierarchyManager.LOCATION_LOCKSCREEN Scenes.Communal -> MediaHierarchyManager.LOCATION_COMMUNAL_HUB else -> MediaHierarchyManager.LOCATION_UNKNOWN @@ -69,6 +70,7 @@ object MediaCarouselStateLoader { /** State for media carousel. */ sealed interface State { val transitionProgress: Float + // TODO b/368368388: implement media squishiness val squishFraction: () -> Float @MediaLocation val startLocation: Int @@ -100,7 +102,7 @@ object MediaCarouselStateLoader { } /** Returns the state of media carousel */ - fun SceneScope.stateForMediaCarouselContent(isInSplitShade: Boolean): State { + fun ContentScope.stateForMediaCarouselContent(isInSplitShade: Boolean): State { return when (val transitionState = layoutState.transitionState) { is TransitionState.Idle -> { if (MediaContentPicker.contents.contains(transitionState.currentScene)) { @@ -109,6 +111,7 @@ object MediaCarouselStateLoader { State.Gone } } + is TransitionState.Transition.ChangeScene -> with(transitionState) { if ( @@ -130,6 +133,7 @@ object MediaCarouselStateLoader { State.Gone } } + is TransitionState.Transition.OverlayTransition -> with(transitionState) { if ( diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt index d52323295db7..215a43382b06 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/media/controls/ui/composable/MediaContentPicker.kt @@ -24,7 +24,6 @@ import com.android.compose.animation.scene.StaticElementContentPicker import com.android.compose.animation.scene.content.state.TransitionState import com.android.systemui.scene.shared.model.Overlays import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.shade.shared.flag.DualShade /** [ElementContentPicker] implementation for the media carousel object. */ object MediaContentPicker : StaticElementContentPicker { @@ -46,8 +45,11 @@ object MediaContentPicker : StaticElementContentPicker { toContentZIndex: Float, ): ContentKey { return when { - shouldElevateMedia(transition) -> { - if (DualShade.isEnabled) Overlays.NotificationsShade else Scenes.Shade + transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade) -> { + Scenes.Shade + } + transition.isTransitioningBetween(Scenes.Lockscreen, Overlays.NotificationsShade) -> { + Overlays.NotificationsShade } transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Communal) -> { Scenes.Lockscreen @@ -71,14 +73,12 @@ object MediaContentPicker : StaticElementContentPicker { } } } - - /** Returns true when the media should be laid on top of the rest for the given [transition]. */ - fun shouldElevateMedia(transition: TransitionState.Transition): Boolean { - return transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade) || - transition.isTransitioningBetween(Scenes.Lockscreen, Overlays.NotificationsShade) - } } +/** Whether media should be laid on top of the rest for the given [transition]. */ fun MediaContentPicker.shouldElevateMedia(layoutState: SceneTransitionLayoutState): Boolean { - return layoutState.currentTransition?.let { shouldElevateMedia(it) } ?: false + return layoutState.currentTransition?.let { transition -> + transition.isTransitioningBetween(Scenes.Lockscreen, Scenes.Shade) || + transition.isTransitioningBetween(Scenes.Lockscreen, Overlays.NotificationsShade) + } ?: false } 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 183929ca6c6a..a6918a7c5ffe 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 @@ -96,9 +96,7 @@ import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadi 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.Overlays import com.android.systemui.scene.shared.model.Scenes -import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.notification.stack.shared.model.AccessibilityScrollEvent import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds @@ -124,12 +122,6 @@ object Notifications { } } -private val notificationsShadeContentKey: ContentKey - get() = if (DualShade.isEnabled) Overlays.NotificationsShade else Scenes.Shade - -private val quickSettingsShadeContentKey: ContentKey - get() = if (DualShade.isEnabled) Overlays.QuickSettingsShade else Scenes.QuickSettings - /** * Adds the space where heads up notifications can appear in the scene. This should generally be the * entire size of the scene. @@ -270,7 +262,12 @@ fun ContentScope.ConstrainedNotificationStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, - useHunBounds = { shouldUseLockscreenHunBounds(layoutState.transitionState) }, + useHunBounds = { + shouldUseLockscreenHunBounds( + layoutState.transitionState, + viewModel.quickSettingsShadeContentKey, + ) + }, modifier = Modifier.align(Alignment.TopCenter), ) NotificationStackCutoffGuideline( @@ -494,11 +491,11 @@ fun ContentScope.NotificationScrollingStack( if ( scrimOffset.value < 0 && (layoutState.isTransitioning( - from = notificationsShadeContentKey, + from = viewModel.notificationsShadeContentKey, to = Scenes.Gone, ) || layoutState.isTransitioning( - from = notificationsShadeContentKey, + from = viewModel.notificationsShadeContentKey, to = Scenes.Lockscreen, )) ) { @@ -527,6 +524,7 @@ fun ContentScope.NotificationScrollingStack( shouldAnimateScrimCornerRadius( layoutState, shouldPunchHoleBehindScrim, + viewModel.notificationsShadeContentKey, ), ) .let { scrimRounding.value.toRoundedCornerShape(it) } @@ -613,7 +611,12 @@ fun ContentScope.NotificationScrollingStack( HeadsUpNotificationSpace( stackScrollView = stackScrollView, viewModel = viewModel, - useHunBounds = { !shouldUseLockscreenHunBounds(layoutState.transitionState) }, + useHunBounds = { + !shouldUseLockscreenHunBounds( + layoutState.transitionState, + viewModel.quickSettingsShadeContentKey, + ) + }, modifier = Modifier.padding(top = stackTopPadding), ) } @@ -720,20 +723,24 @@ private fun shouldUseLockscreenStackBounds(state: TransitionState): Boolean { return state is TransitionState.Idle && state.isOnLockscreen() } -private fun shouldUseLockscreenHunBounds(state: TransitionState): Boolean { +private fun shouldUseLockscreenHunBounds( + state: TransitionState, + quickSettingsShade: ContentKey, +): Boolean { return when (state) { is TransitionState.Idle -> state.isOnLockscreen() is TransitionState.Transition -> - state.isTransitioning(from = quickSettingsShadeContentKey, to = Scenes.Lockscreen) + state.isTransitioning(from = quickSettingsShade, to = Scenes.Lockscreen) } } private fun shouldAnimateScrimCornerRadius( state: SceneTransitionLayoutState, shouldPunchHoleBehindScrim: Boolean, + notificationsShade: ContentKey, ): Boolean { return shouldPunchHoleBehindScrim || - state.isTransitioning(from = notificationsShadeContentKey, to = Scenes.Lockscreen) + state.isTransitioning(from = notificationsShade, to = Scenes.Lockscreen) } private fun calculateCornerRadius( 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 f7ce2153b0ec..25b673bee1cd 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 @@ -72,9 +72,10 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.compose.animation.Expandable -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.fadingBackground import com.android.compose.theme.colorAttr +import com.android.systemui.Flags.notificationShadeBlur import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.ui.compose.Icon @@ -90,7 +91,7 @@ import com.android.systemui.res.R import kotlinx.coroutines.launch @Composable -fun SceneScope.FooterActionsWithAnimatedVisibility( +fun ContentScope.FooterActionsWithAnimatedVisibility( viewModel: FooterActionsViewModel, isCustomizing: Boolean, customizingAnimationDuration: Int, @@ -163,14 +164,16 @@ fun FooterActions( } } - val backgroundColor = colorAttr(R.attr.underSurface) + val backgroundColor = + if (!notificationShadeBlur()) colorAttr(R.attr.underSurface) else Color.Transparent + val backgroundAlphaValue = if (!notificationShadeBlur()) backgroundAlpha::value else ({ 0f }) val contentColor = MaterialTheme.colorScheme.onSurface val backgroundTopRadius = dimensionResource(R.dimen.qs_corner_radius) val backgroundModifier = - remember(backgroundColor, backgroundAlpha, backgroundTopRadius) { + remember(backgroundColor, backgroundAlphaValue, backgroundTopRadius) { Modifier.fadingBackground( backgroundColor, - backgroundAlpha::value, + backgroundAlphaValue, RoundedCornerShape(topStart = backgroundTopRadius, topEnd = backgroundTopRadius), ) } @@ -253,6 +256,7 @@ private fun RowScope.ForegroundServicesButton( } else { NumberButton( model.foregroundServicesCount, + contentDescription = model.text, showNewDot = model.hasNewChanges, onClick = model.onClick, ) @@ -281,6 +285,7 @@ fun IconButton(model: FooterActionsButtonViewModel, modifier: Modifier = Modifie @Composable private fun NumberButton( number: Int, + contentDescription: String, showNewDot: Boolean, onClick: (Expandable) -> Unit, modifier: Modifier = Modifier, @@ -311,7 +316,10 @@ private fun NumberButton( ) { Text( number.toString(), - modifier = Modifier.align(Alignment.Center), + modifier = + Modifier.align(Alignment.Center).semantics { + this.contentDescription = contentDescription + }, style = MaterialTheme.typography.bodyLarge, color = colorAttr(R.attr.onShadeInactiveVariant), // TODO(b/242040009): This should only use a standard text style instead and diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt index 58336c2e9d41..b826187578e0 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt @@ -36,10 +36,10 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.MovableElementContentPicker import com.android.compose.animation.scene.MovableElementKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.SceneTransitionLayoutState import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.content.state.TransitionState @@ -98,7 +98,7 @@ object QuickSettings { } } -private fun SceneScope.stateForQuickSettingsContent( +private fun ContentScope.stateForQuickSettingsContent( isSplitShade: Boolean, squishiness: () -> Float = { QuickSettings.SharedValues.SquishinessValues.Default }, ): QSSceneAdapter.State { @@ -141,7 +141,7 @@ private fun SceneScope.stateForQuickSettingsContent( /** * This composable will show QuickSettingsContent in the correct state (as determined by its - * [SceneScope]). + * [ContentScope]). * * If adding to scenes not in: * * QuickSettingsScene @@ -153,7 +153,7 @@ private fun SceneScope.stateForQuickSettingsContent( * * this doc. */ @Composable -fun SceneScope.QuickSettings( +fun ContentScope.QuickSettings( qsSceneAdapter: QSSceneAdapter, heightProvider: () -> Int, isSplitShade: Boolean, 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 26cf7066124a..4bfbb3a908fa 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 @@ -68,7 +68,7 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateSceneDpAsState @@ -144,7 +144,7 @@ constructor( } @Composable - override fun SceneScope.Content(modifier: Modifier) { + override fun ContentScope.Content(modifier: Modifier) { QuickSettingsScene( notificationStackScrollView = notificationStackScrollView.get(), viewModelFactory = contentViewModelFactory, @@ -164,7 +164,7 @@ constructor( } @Composable -private fun SceneScope.QuickSettingsScene( +private fun ContentScope.QuickSettingsScene( notificationStackScrollView: NotificationScrollView, viewModelFactory: QuickSettingsSceneContentViewModel.Factory, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt index 9ee25c3404ec..2175a59e8e4d 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt @@ -25,7 +25,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateContentDpAsState @@ -71,7 +71,7 @@ constructor( } @Composable - override fun SceneScope.Content(modifier: Modifier) { + override fun ContentScope.Content(modifier: Modifier) { val isIdleAndNotOccluded by remember { derivedStateOf { diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt index 8d8ab8ee7949..6c80c69b7a34 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/Scene.kt @@ -18,8 +18,8 @@ package com.android.systemui.scene.ui.composable import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.systemui.lifecycle.Activatable /** @@ -35,5 +35,5 @@ interface Scene : Activatable, ActionableContent { /** Uniquely-identifying key for this scene. The key must be unique within its container. */ val key: SceneKey - @Composable fun SceneScope.Content(modifier: Modifier) + @Composable fun ContentScope.Content(modifier: Modifier) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt index bfcde7dab6d2..3131b539c6af 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt @@ -58,9 +58,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.max import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.animateElementFloatAsState import com.android.compose.animation.scene.content.state.TransitionState @@ -122,7 +122,7 @@ object ShadeHeader { } @Composable -fun SceneScope.CollapsedShadeHeader( +fun ContentScope.CollapsedShadeHeader( viewModelFactory: ShadeHeaderViewModel.Factory, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -264,7 +264,7 @@ fun SceneScope.CollapsedShadeHeader( } @Composable -fun SceneScope.ExpandedShadeHeader( +fun ContentScope.ExpandedShadeHeader( viewModelFactory: ShadeHeaderViewModel.Factory, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController, @@ -339,7 +339,7 @@ fun SceneScope.ExpandedShadeHeader( } @Composable -private fun SceneScope.Clock(scale: Float, viewModel: ShadeHeaderViewModel, modifier: Modifier) { +private fun ContentScope.Clock(scale: Float, viewModel: ShadeHeaderViewModel, modifier: Modifier) { val layoutDirection = LocalLayoutDirection.current Element(key = ShadeHeader.Elements.Clock, modifier = modifier) { @@ -446,7 +446,7 @@ private fun ShadeCarrierGroup(viewModel: ShadeHeaderViewModel, modifier: Modifie } @Composable -private fun SceneScope.StatusIcons( +private fun ContentScope.StatusIcons( viewModel: ShadeHeaderViewModel, createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager, statusBarIconController: StatusBarIconController, @@ -548,7 +548,10 @@ private fun SystemIconContainer( } @Composable -private fun SceneScope.PrivacyChip(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) { +private fun ContentScope.PrivacyChip( + viewModel: ShadeHeaderViewModel, + modifier: Modifier = Modifier, +) { val privacyList by viewModel.privacyItems.collectAsStateWithLifecycle() AndroidView( 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 0d3bab24f68f..f829a0d6facf 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 @@ -62,9 +62,9 @@ import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.LowestZIndexContentPicker -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.animateContentDpAsState @@ -160,7 +160,7 @@ constructor( override val userActions: Flow<Map<UserAction, UserActionResult>> = actionsViewModel.actions @Composable - override fun SceneScope.Content(modifier: Modifier) = + override fun ContentScope.Content(modifier: Modifier) = ShadeScene( notificationStackScrollView.get(), viewModel = @@ -193,7 +193,7 @@ constructor( } @Composable -private fun SceneScope.ShadeScene( +private fun ContentScope.ShadeScene( notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneContentViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, @@ -242,7 +242,7 @@ private fun SceneScope.ShadeScene( } @Composable -private fun SceneScope.SingleShade( +private fun ContentScope.SingleShade( notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneContentViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, @@ -410,7 +410,7 @@ private fun SceneScope.SingleShade( } @Composable -private fun SceneScope.SplitShade( +private fun ContentScope.SplitShade( notificationStackScrollView: NotificationScrollView, viewModel: ShadeSceneContentViewModel, notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel, @@ -632,7 +632,7 @@ private fun SceneScope.SplitShade( } @Composable -private fun SceneScope.ShadeMediaCarousel( +private fun ContentScope.ShadeMediaCarousel( isVisible: Boolean, isInRow: Boolean, mediaHost: MediaHost, 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 25892c5a75cc..d9e8f02f005b 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 @@ -19,7 +19,6 @@ package com.android.systemui.volume.panel.component.volume.ui.composable 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 @@ -70,8 +69,6 @@ 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) @Composable fun ColumnVolumeSliders( viewModels: List<SliderViewModel>, @@ -144,8 +141,7 @@ fun ColumnVolumeSliders( VolumeSlider( modifier = - Modifier.padding(top = 16.dp) - .fillMaxWidth() + Modifier.fillMaxWidth() .animateEnterExit( enter = enterTransition( @@ -157,7 +153,10 @@ fun ColumnVolumeSliders( index = index, totalCount = viewModels.size, ), - ), + ) + .thenIf(!Flags.volumeRedesign()) { + Modifier.padding(top = 16.dp) + }, state = sliderState, onValueChange = { newValue: Float -> sliderViewModel.onValueChanged(sliderState, newValue) diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt index 5f991fbb50df..bdd0da9ce4a4 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt @@ -17,10 +17,12 @@ package com.android.systemui.volume.panel.component.volume.ui.composable import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.foundation.basicMarquee import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.interaction.MutableInteractionSource @@ -33,6 +35,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon as MaterialIcon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text @@ -47,6 +50,7 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.CustomAccessibilityAction import androidx.compose.ui.semantics.ProgressBarRangeInfo import androidx.compose.ui.semantics.clearAndSetSemantics @@ -67,6 +71,7 @@ import com.android.systemui.haptics.slider.SeekableSliderTrackerConfig import com.android.systemui.haptics.slider.SliderHapticFeedbackConfig import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.lifecycle.rememberViewModel +import com.android.systemui.res.R import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState import kotlin.math.round import kotlinx.coroutines.flow.distinctUntilChanged @@ -98,7 +103,7 @@ fun VolumeSlider( } val value by valueState(state) - Column(modifier) { + Column(modifier = modifier.animateContentSize(), verticalArrangement = Arrangement.Top) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp), modifier = Modifier.fillMaxWidth().height(40.dp), @@ -127,7 +132,7 @@ fun VolumeSlider( enabled = state.isEnabled, modifier = Modifier.height(40.dp) - .padding(vertical = 8.dp) + .padding(top = 4.dp, bottom = 12.dp) .sysuiResTag(state.label) .clearAndSetSemantics { if (state.isEnabled) { @@ -168,6 +173,28 @@ fun VolumeSlider( } }, ) + state.disabledMessage?.let { disabledMessage -> + AnimatedVisibility(visible = !state.isEnabled) { + Row( + modifier = Modifier.padding(bottom = 12.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + MaterialIcon( + painter = painterResource(R.drawable.ic_error_outline), + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(16.dp), + ) + Text( + text = disabledMessage, + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.labelSmall, + modifier = Modifier.basicMarquee(), + ) + } + } + } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt index 6349c1406a12..bc3013239289 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt @@ -37,18 +37,17 @@ fun VolumePanelComposeScope.VerticalVolumePanelContent( layout: ComponentsLayout, modifier: Modifier = Modifier, ) { - Column( - modifier = modifier.verticalScroll(rememberScrollState()), - verticalArrangement = Arrangement.spacedBy(20.dp), - ) { + Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(20.dp)) { for (component in layout.headerComponents) { AnimatedVisibility(component.isVisible) { with(component.component as ComposeVolumePanelUiComponent) { Content(Modifier) } } } - for (component in layout.contentComponents) { - AnimatedVisibility(component.isVisible) { - with(component.component as ComposeVolumePanelUiComponent) { Content(Modifier) } + Column(Modifier.verticalScroll(rememberScrollState())) { + for (component in layout.contentComponents) { + AnimatedVisibility(component.isVisible) { + with(component.component as ComposeVolumePanelUiComponent) { Content(Modifier) } + } } } diff --git a/packages/SystemUI/compose/scene/Android.bp b/packages/SystemUI/compose/scene/Android.bp index 682c49cfd19c..090e9ccedda0 100644 --- a/packages/SystemUI/compose/scene/Android.bp +++ b/packages/SystemUI/compose/scene/Android.bp @@ -42,6 +42,7 @@ android_library { "androidx.compose.material3_material3", "PlatformComposeCore", + "mechanics", ], kotlincflags: ["-Xjvm-default=all"], diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateOverlay.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateOverlay.kt index 28116cb435e4..7d41a266adf2 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateOverlay.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateOverlay.kt @@ -17,6 +17,7 @@ package com.android.compose.animation.scene import com.android.compose.animation.scene.content.state.TransitionState +import com.android.mechanics.GestureContext import kotlinx.coroutines.CoroutineScope /** Trigger a one-off transition to show or hide an overlay. */ @@ -118,6 +119,7 @@ private class OneOffShowOrHideOverlayTransition( override val isInitiatedByUserInput: Boolean = false override val isUserInputOngoing: Boolean = false + override val gestureContext: GestureContext? = null override suspend fun run() { oneOffAnimation.run() @@ -144,6 +146,7 @@ private class OneOffOverlayReplacingTransition( override val isInitiatedByUserInput: Boolean = false override val isUserInputOngoing: Boolean = false + override val gestureContext: GestureContext? = null override suspend fun run() { oneOffAnimation.run() diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt index 86be4a44f3cb..dad4e2491be0 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt @@ -17,6 +17,7 @@ package com.android.compose.animation.scene import com.android.compose.animation.scene.content.state.TransitionState +import com.android.mechanics.GestureContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -193,6 +194,7 @@ private class OneOffSceneTransition( get() = oneOffAnimation.progressVelocity override val isUserInputOngoing: Boolean = false + override val gestureContext: GestureContext? = null override suspend fun run() { oneOffAnimation.run() diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt index 633328a836e3..916d85a80e77 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt @@ -31,6 +31,8 @@ import com.android.compose.animation.scene.content.state.TransitionState.Compani import com.android.compose.animation.scene.effect.GestureEffect import com.android.compose.gesture.NestedDraggable import com.android.compose.ui.util.SpaceVectorConverter +import com.android.mechanics.DistanceGestureContext +import com.android.mechanics.spec.InputDirection import kotlin.math.absoluteValue import kotlinx.coroutines.launch @@ -114,7 +116,14 @@ internal class DraggableHandler( else -> error("Unknown result $result ($upOrLeftResult $downOrRightResult)") } - return createSwipeAnimation(layoutImpl, result, isUpOrLeft, orientation) + val gestureContext = + DistanceGestureContext( + initialDragOffset = 0f, + initialDirection = if (isUpOrLeft) InputDirection.Min else InputDirection.Max, + directionChangeSlop = layoutImpl.directionChangeSlop, + ) + + return createSwipeAnimation(layoutImpl, result, isUpOrLeft, orientation, gestureContext) } private fun resolveSwipeSource(startedPosition: Offset): SwipeSource.Resolved? { @@ -316,6 +325,7 @@ private class DragControllerImpl( // when the distance is defined. delta } + distance > 0f -> desiredOffset.fastCoerceIn(0f, distance) else -> desiredOffset.fastCoerceIn(distance, 0f) } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt index 8a6a0d6dbb99..621166e1823a 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt @@ -26,6 +26,8 @@ import com.android.compose.animation.scene.UserActionResult.HideOverlay import com.android.compose.animation.scene.UserActionResult.ReplaceByOverlay import com.android.compose.animation.scene.UserActionResult.ShowOverlay import com.android.compose.animation.scene.transition.animateProgress +import com.android.mechanics.ProvidedGestureContext +import com.android.mechanics.spec.InputDirection import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map @@ -55,6 +57,8 @@ internal fun PredictiveBackHandler( // compute the distance. In our case the distance is always 1f. orientation = Orientation.Horizontal, distance = 1f, + gestureContext = + ProvidedGestureContext(dragOffset = 0f, direction = InputDirection.Max), ) animateProgress( diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt index 4e389471d1d0..a1117e1bc1db 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.input.pointer.PointerType import androidx.compose.ui.layout.LookaheadScope import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset @@ -263,9 +264,6 @@ interface BaseContentScope : ElementStateScope { ) } -@Deprecated("Use ContentScope instead", ReplaceWith("ContentScope")) -typealias SceneScope = ContentScope - @Stable @ElementDsl interface ContentScope : BaseContentScope { @@ -716,6 +714,7 @@ internal fun SceneTransitionLayoutForTesting( builder: SceneTransitionLayoutScope.() -> Unit, ) { val density = LocalDensity.current + val directionChangeSlop = LocalViewConfiguration.current.touchSlop val layoutDirection = LocalLayoutDirection.current val animationScope = rememberCoroutineScope() val layoutImpl = remember { @@ -731,6 +730,7 @@ internal fun SceneTransitionLayoutForTesting( elements = sharedElementMap, ancestors = ancestors, lookaheadScope = lookaheadScope, + directionChangeSlop = directionChangeSlop, ) .also { onLayoutImpl?.invoke(it) } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt index b4c449d0566c..38ad0a80fd00 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt @@ -88,6 +88,14 @@ internal class SceneTransitionLayoutImpl( internal val animationScope: CoroutineScope, /** + * Number of pixels a gesture has to travel in the opposite direction to for its intrinsic + * direction to change. + * + * Used to determine the direction of [Transition.gestureContext]. + */ + internal val directionChangeSlop: Float, + + /** * The map of [Element]s. * * Important: [Element]s from this map should never be accessed during composition because the @@ -368,6 +376,7 @@ internal class SceneTransitionLayoutImpl( error("Transition to the same scene is not supported. ${details()}") } } + is UserActionResult.ReplaceByOverlay -> { check(key is OverlayKey) { "ReplaceByOverlay() can only be used for overlays, not scenes. ${details()}" @@ -377,6 +386,7 @@ internal class SceneTransitionLayoutImpl( "Transition to the same overlay is not supported. ${details()}" } } + is UserActionResult.ShowOverlay, is UserActionResult.HideOverlay -> { /* Always valid. */ @@ -443,8 +453,10 @@ internal class SceneTransitionLayoutImpl( maybeAdd(transition.toScene) maybeAdd(transition.fromScene) } + is TransitionState.Transition.ShowOrHideOverlay -> maybeAdd(transition.fromOrToScene) + is TransitionState.Transition.ReplaceOverlay -> {} } } @@ -510,6 +522,7 @@ internal class SceneTransitionLayoutImpl( is TransitionState.Transition.ChangeScene -> {} is TransitionState.Transition.ShowOrHideOverlay -> maybeAdd(transition.overlay) + is TransitionState.Transition.ReplaceOverlay -> { maybeAdd(transition.fromOverlay) maybeAdd(transition.toOverlay) diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt index b1d6d1efc264..4137f5f5725b 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SwipeAnimation.kt @@ -21,12 +21,13 @@ import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.AnimationVector1D import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.util.fastCoerceIn import com.android.compose.animation.scene.content.state.TransitionState import com.android.compose.animation.scene.content.state.TransitionState.Companion.DistanceUnspecified +import com.android.mechanics.GestureContext +import com.android.mechanics.MutableDragOffsetGestureContext import kotlin.math.absoluteValue import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.launch @@ -37,6 +38,7 @@ internal fun createSwipeAnimation( isUpOrLeft: Boolean, orientation: Orientation, distance: Float, + gestureContext: MutableDragOffsetGestureContext, ): SwipeAnimation<*> { return createSwipeAnimation( layoutState, @@ -47,6 +49,7 @@ internal fun createSwipeAnimation( contentForUserActions = { error("Computing contentForUserActions requires a SceneTransitionLayoutImpl") }, + gestureContext = gestureContext, ) } @@ -55,6 +58,7 @@ internal fun createSwipeAnimation( result: UserActionResult, isUpOrLeft: Boolean, orientation: Orientation, + gestureContext: MutableDragOffsetGestureContext, distance: Float = DistanceUnspecified, ): SwipeAnimation<*> { var lastDistance = distance @@ -98,6 +102,7 @@ internal fun createSwipeAnimation( orientation, distance = ::distance, contentForUserActions = { layoutImpl.contentForUserActions().key }, + gestureContext = gestureContext, ) } @@ -108,6 +113,7 @@ private fun createSwipeAnimation( orientation: Orientation, distance: (SwipeAnimation<*>) -> Float, contentForUserActions: () -> ContentKey, + gestureContext: MutableDragOffsetGestureContext, ): SwipeAnimation<*> { fun <T : ContentKey> swipeAnimation(fromContent: T, toContent: T): SwipeAnimation<T> { return SwipeAnimation( @@ -118,6 +124,7 @@ private fun createSwipeAnimation( isUpOrLeft = isUpOrLeft, requiresFullDistanceSwipe = result.requiresFullDistanceSwipe, distance = distance, + gestureContext = gestureContext, ) } @@ -132,6 +139,7 @@ private fun createSwipeAnimation( ) .swipeAnimation } + is UserActionResult.ShowOverlay -> { val fromScene = layoutState.currentScene val overlay = result.overlay @@ -144,6 +152,7 @@ private fun createSwipeAnimation( ) .swipeAnimation } + is UserActionResult.HideOverlay -> { val toScene = layoutState.currentScene val overlay = result.overlay @@ -156,11 +165,13 @@ private fun createSwipeAnimation( ) .swipeAnimation } + is UserActionResult.ReplaceByOverlay -> { val fromOverlay = when (val contentForUserActions = contentForUserActions()) { is SceneKey -> error("ReplaceByOverlay can only be called when an overlay is shown") + is OverlayKey -> contentForUserActions } @@ -186,8 +197,8 @@ internal class SwipeAnimation<T : ContentKey>( val requiresFullDistanceSwipe: Boolean, private val distance: (SwipeAnimation<T>) -> Float, currentContent: T = fromContent, - dragOffset: Float = 0f, -) { + private val gestureContext: MutableDragOffsetGestureContext, +) : MutableDragOffsetGestureContext by gestureContext { /** The [TransitionState.Transition] whose implementation delegates to this [SwipeAnimation]. */ lateinit var contentTransition: TransitionState.Transition @@ -254,9 +265,6 @@ internal class SwipeAnimation<T : ContentKey>( val isInPreviewStage: Boolean get() = contentTransition.previewTransformationSpec != null && currentContent == fromContent - /** The current offset caused by the drag gesture. */ - var dragOffset by mutableFloatStateOf(dragOffset) - /** The offset animation that animates the offset once the user lifts their finger. */ private var offsetAnimation: Animatable<Float, AnimationVector1D>? by mutableStateOf(null) private val offsetAnimationRunnable = CompletableDeferred<suspend () -> Unit>() @@ -387,6 +395,7 @@ internal class SwipeAnimation<T : ContentKey>( return when (val transition = contentTransition) { is TransitionState.Transition.ChangeScene -> layoutState.canChangeScene(targetContent as SceneKey) + is TransitionState.Transition.ShowOrHideOverlay -> { if (targetContent == transition.overlay) { layoutState.canShowOverlay(transition.overlay) @@ -394,6 +403,7 @@ internal class SwipeAnimation<T : ContentKey>( layoutState.canHideOverlay(transition.overlay) } } + is TransitionState.Transition.ReplaceOverlay -> { val to = targetContent as OverlayKey val from = @@ -464,6 +474,8 @@ private class ChangeSceneSwipeTransition( override val isUserInputOngoing: Boolean get() = swipeAnimation.isUserInputOngoing + override val gestureContext: GestureContext = swipeAnimation + override suspend fun run() { swipeAnimation.run() } @@ -515,6 +527,8 @@ private class ShowOrHideOverlaySwipeTransition( override val isUserInputOngoing: Boolean get() = swipeAnimation.isUserInputOngoing + override val gestureContext: GestureContext = swipeAnimation + override suspend fun run() { swipeAnimation.run() } @@ -562,6 +576,8 @@ private class ReplaceOverlaySwipeTransition( override val isUserInputOngoing: Boolean get() = swipeAnimation.isUserInputOngoing + override val gestureContext: GestureContext = swipeAnimation + override suspend fun run() { swipeAnimation.run() } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt index f772f1a0b4a6..e9542c830b4d 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/state/TransitionState.kt @@ -33,6 +33,7 @@ import com.android.compose.animation.scene.TransformationSpec import com.android.compose.animation.scene.TransformationSpecImpl import com.android.compose.animation.scene.TransitionKey import com.android.internal.jank.Cuj.CujType +import com.android.mechanics.GestureContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -238,6 +239,9 @@ sealed interface TransitionState { /** Whether user input is currently driving the transition. */ abstract val isUserInputOngoing: Boolean + /** Additional gesture context whenever the transition is driven by a user gesture. */ + abstract val gestureContext: GestureContext? + /** The CUJ covered by this transition. */ @CujType val cuj: Int? diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt index c6912d5e4ad2..819cec712808 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/Seek.kt @@ -29,6 +29,8 @@ import com.android.compose.animation.scene.SwipeAnimation import com.android.compose.animation.scene.TransitionKey import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.createSwipeAnimation +import com.android.mechanics.ProvidedGestureContext +import com.android.mechanics.spec.InputDirection import kotlin.coroutines.cancellation.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job @@ -126,6 +128,9 @@ private suspend fun MutableSceneTransitionLayoutState.seek( // overscroll, which is disabled for progress-based transitions. orientation = Orientation.Horizontal, isUpOrLeft = false, + // There is no gesture information available here - animateProgress + // will set the progress as the dragOffset. + gestureContext = ProvidedGestureContext(0f, InputDirection.Max), ) animateProgress( diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt index 4a0c330be4f8..ef360770bc41 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt @@ -41,7 +41,9 @@ import com.android.compose.animation.scene.subjects.assertThat import com.android.compose.gesture.NestedDraggable import com.android.compose.test.MonotonicClockTestScope import com.android.compose.test.runMonotonicClockTest +import com.android.mechanics.spec.InputDirection import com.google.common.truth.Truth.assertThat +import kotlin.math.nextUp import kotlin.math.sign import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred @@ -106,6 +108,7 @@ class DraggableHandlerTest { } val transitionInterceptionThreshold = 0.05f + val directionChangeSlop = 10f private val layoutImpl = SceneTransitionLayoutImpl( @@ -120,6 +123,7 @@ class DraggableHandlerTest { // Use testScope and not backgroundScope here because backgroundScope does not // work well with advanceUntilIdle(), which is used by some tests. animationScope = testScope, + directionChangeSlop = directionChangeSlop, ) .apply { setContentsAndLayoutTargetSizeForTest(LAYOUT_SIZE) } @@ -871,4 +875,65 @@ class DraggableHandlerTest { assertThat(layoutState.transitionState).hasCurrentScene(SceneA) assertThat(layoutState.transitionState).hasCurrentOverlays(OverlayB) } + + @Test + fun gestureContext_dragOffset_matchesOverSlopAtBeginning() = runGestureTest { + val overSlop = down(fractionOfScreen = 0.1f) + onDragStarted(overSlop = overSlop) + + val gestureContext = assertThat(transitionState).hasGestureContext() + assertThat(gestureContext.dragOffset).isEqualTo(overSlop) + } + + @Test + fun gestureContext_dragOffset_getsUpdatedOnEachDragEvent() = runGestureTest { + val dragController = onDragStarted(overSlop = down(fractionOfScreen = 0.1f)) + + val gestureContext = assertThat(transitionState).hasGestureContext() + val initialDragOffset = gestureContext.dragOffset + + dragController.onDragDelta(pixels = 3.5f) + assertThat(gestureContext.dragOffset).isEqualTo(initialDragOffset + 3.5f) + + dragController.onDragDelta(pixels = -2f) + assertThat(gestureContext.dragOffset).isEqualTo(initialDragOffset + 3.5f - 2f) + } + + @Test + fun gestureContext_direction_swipeDown_startsWithMaxDirection() = runGestureTest { + onDragStarted(overSlop = down(fractionOfScreen = 0.1f)) + + val gestureContext = assertThat(transitionState).hasGestureContext() + assertThat(gestureContext.direction).isEqualTo(InputDirection.Max) + } + + @Test + fun gestureContext_direction_swipeUp_startsWithMinDirection() = runGestureTest { + onDragStarted(overSlop = up(fractionOfScreen = 0.1f)) + + val gestureContext = assertThat(transitionState).hasGestureContext() + assertThat(gestureContext.direction).isEqualTo(InputDirection.Min) + } + + @Test + fun gestureContext_direction_withinDirectionSlop_staysSame() = runGestureTest { + val dragController = onDragStarted(overSlop = up(fractionOfScreen = .2f)) + + val gestureContext = assertThat(transitionState).hasGestureContext() + assertThat(gestureContext.direction).isEqualTo(InputDirection.Min) + + dragController.onDragDelta(pixels = directionChangeSlop) + assertThat(gestureContext.direction).isEqualTo(InputDirection.Min) + } + + @Test + fun gestureContext_direction_overDirectionSlop_isChanged() = runGestureTest { + val dragController = onDragStarted(overSlop = up(fractionOfScreen = .2f)) + + val gestureContext = assertThat(transitionState).hasGestureContext() + assertThat(gestureContext.direction).isEqualTo(InputDirection.Min) + + dragController.onDragDelta(pixels = directionChangeSlop.nextUp()) + assertThat(gestureContext.direction).isEqualTo(InputDirection.Max) + } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt index 005146997813..b405fbe89302 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt @@ -2095,7 +2095,7 @@ class ElementTest { val foo = ElementKey("Foo", placeAllCopies = true) @Composable - fun SceneScope.Foo(size: Dp, modifier: Modifier = Modifier) { + fun ContentScope.Foo(size: Dp, modifier: Modifier = Modifier) { Box(modifier.element(foo).size(size)) } @@ -2159,7 +2159,7 @@ class ElementTest { // Foo is a simple element that does not move or resize during the transition. @Composable - fun SceneScope.Foo(modifier: Modifier = Modifier) { + fun ContentScope.Foo(modifier: Modifier = Modifier) { Box( modifier .element(TestElements.Foo) @@ -2211,7 +2211,7 @@ class ElementTest { @Ignore("b/363964445") fun interruption_considerPreviousUniqueState() { @Composable - fun SceneScope.Foo(modifier: Modifier = Modifier) { + fun ContentScope.Foo(modifier: Modifier = Modifier) { Box(modifier.element(TestElements.Foo).size(50.dp)) } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt index b4c8ad7c3327..9e1bae577ed2 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MovableElementTest.kt @@ -373,7 +373,7 @@ class MovableElementTest { val fooParentInOverlayTag = "fooParentTagInOverlay" @Composable - fun SceneScope.Foo(modifier: Modifier = Modifier) { + fun ContentScope.Foo(modifier: Modifier = Modifier) { // Foo wraps its content, so there is no way for STL to know its size in advance. MovableElement(foo, modifier) { content { Box(Modifier.size(fooSize)) } } } diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt index bad4c6298e6b..93fa51654ca1 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/OverlayTest.kt @@ -547,7 +547,7 @@ class OverlayTest { val sharedIntValueByContent = mutableMapOf<ContentKey, Int>() @Composable - fun SceneScope.animateContentInt(targetValue: Int) { + fun ContentScope.animateContentInt(targetValue: Int) { val animatedValue = animateContentIntAsState(targetValue, sharedIntKey) LaunchedEffect(animatedValue) { try { diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt index 6db98a874787..8db7dbca2474 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/subjects/TransitionStateSubject.kt @@ -19,6 +19,7 @@ package com.android.compose.animation.scene.subjects import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.content.state.TransitionState +import com.android.mechanics.GestureContext import com.google.common.truth.Fact.simpleFact import com.google.common.truth.FailureMetadata import com.google.common.truth.Subject @@ -98,6 +99,17 @@ private constructor(metadata: FailureMetadata, private val actual: TransitionSta return actual as TransitionState.Transition.ReplaceOverlay } + fun hasGestureContext(): GestureContext { + if (actual !is TransitionState.Transition) { + failWithActual(simpleFact("expected to be TransitionState.Transition")) + } + + val gestureContext = ((actual as TransitionState.Transition).gestureContext) + check("transition.gestureContext").that(gestureContext).isNotNull() + + return checkNotNull(gestureContext) + } + companion object { fun transitionStates() = Factory { metadata, actual: TransitionState -> TransitionStateSubject(metadata, actual) diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt index b9d01c2eaa3b..c22c19867dbb 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestOverlayTransition.kt @@ -20,6 +20,7 @@ import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.SceneTransitionLayoutImpl import com.android.compose.animation.scene.content.state.TransitionState.Transition +import com.android.mechanics.GestureContext import kotlinx.coroutines.CompletableDeferred /** A [Transition.ShowOrHideOverlay] for tests that will be finished once [finish] is called. */ @@ -84,6 +85,7 @@ fun transition( override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput override val isUserInputOngoing: Boolean = isUserInputOngoing + override val gestureContext: GestureContext? = null override fun freezeAndAnimateToCurrentState() { if (onFreezeAndAnimate != null) { diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt index 983c429aa58e..139dcd5d5114 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestReplaceOverlayTransition.kt @@ -19,6 +19,7 @@ package com.android.compose.test import com.android.compose.animation.scene.OverlayKey import com.android.compose.animation.scene.SceneTransitionLayoutImpl import com.android.compose.animation.scene.content.state.TransitionState.Transition +import com.android.mechanics.GestureContext import kotlinx.coroutines.CompletableDeferred /** A [Transition.ShowOrHideOverlay] for tests that will be finished once [finish] is called. */ @@ -81,6 +82,7 @@ fun transition( override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput override val isUserInputOngoing: Boolean = isUserInputOngoing + override val gestureContext: GestureContext? = null override fun freezeAndAnimateToCurrentState() { if (onFreezeAndAnimate != null) { diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt index d11951ee4b24..18cd57bb985f 100644 --- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt +++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/test/TestSceneTransition.kt @@ -19,6 +19,7 @@ package com.android.compose.test import com.android.compose.animation.scene.SceneKey import com.android.compose.animation.scene.SceneTransitionLayoutImpl import com.android.compose.animation.scene.content.state.TransitionState.Transition +import com.android.mechanics.GestureContext import kotlinx.coroutines.CompletableDeferred /** A [Transition.ChangeScene] for tests that will be finished once [finish] is called. */ @@ -54,6 +55,7 @@ fun transition( isUserInputOngoing: Boolean = false, onFreezeAndAnimate: ((TestSceneTransition) -> Unit)? = null, replacedTransition: Transition? = null, + gestureContext: GestureContext? = null, ): TestSceneTransition { return object : TestSceneTransition(from, to, replacedTransition) { override val currentScene: SceneKey @@ -76,6 +78,7 @@ fun transition( override val isInitiatedByUserInput: Boolean = isInitiatedByUserInput override val isUserInputOngoing: Boolean = isUserInputOngoing + override val gestureContext: GestureContext? = gestureContext override fun freezeAndAnimateToCurrentState() { if (onFreezeAndAnimate != null) { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/SensorLocation.kt index 2f2f3a35dbaa..552679224bca 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/shared/model/SensorLocation.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/SensorLocation.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.biometrics.shared.model +package com.android.systemui.shared.customization.data /** * Provides current sensor location information in the current screen resolution [scale]. @@ -26,18 +26,40 @@ data class SensorLocation( private val naturalCenterX: Int, private val naturalCenterY: Int, private val naturalRadius: Int, - private val scale: Float = 1f + private val scale: Float = 1f, ) { val centerX: Float get() { return naturalCenterX * scale } + val centerY: Float get() { return naturalCenterY * scale } + val radius: Float get() { return naturalRadius * scale } + + fun encode(): String { + return floatArrayOf( + naturalCenterX.toFloat(), + naturalCenterY.toFloat(), + naturalRadius.toFloat(), + scale, + ) + .joinToString(DELIMITER) + } + + companion object { + + private const val DELIMITER: String = "," + + fun decode(encoded: String): SensorLocation { + val array = encoded.split(DELIMITER).map { it.toFloat() }.toFloatArray() + return SensorLocation(array[0].toInt(), array[1].toInt(), array[2].toInt(), array[3]) + } + } } diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt index 48af2d9f5542..caa6636bde03 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderClient.kt @@ -80,13 +80,6 @@ interface CustomizationProviderClient { fun observeFlags(): Flow<List<Flag>> /** - * Returns [Flow] for observing the variables from the System UI. - * - * @see [queryRuntimeValues] - */ - fun observeRuntimeValues(): Flow<Bundle> - - /** * Returns all available affordances supported by the device, regardless of current slot * placement. */ @@ -291,6 +284,9 @@ class CustomizationProviderClientImpl( Contract.RuntimeValuesTable.KEY_IS_SHADE_LAYOUT_WIDE -> { putBoolean(name, cursor.getInt(valueColumnIndex) == 1) } + Contract.RuntimeValuesTable.KEY_UDFPS_LOCATION -> { + putString(name, cursor.getString(valueColumnIndex)) + } } } } @@ -307,10 +303,6 @@ class CustomizationProviderClientImpl( return observeUri(Contract.FlagsTable.URI).map { queryFlags() } } - override fun observeRuntimeValues(): Flow<Bundle> { - return observeUri(Contract.RuntimeValuesTable.URI).map { queryRuntimeValues() } - } - override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> { return withContext(backgroundDispatcher) { context.contentResolver diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt index cb167eddcea9..2934f070b05f 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt @@ -19,6 +19,7 @@ package com.android.systemui.shared.customization.data.content import android.content.ContentResolver import android.net.Uri +import com.android.systemui.shared.customization.data.SensorLocation /** Contract definitions for querying content about keyguard quick affordances. */ object CustomizationProviderContract { @@ -213,6 +214,11 @@ object CustomizationProviderContract { * be as wide as the entire screen. */ const val KEY_IS_SHADE_LAYOUT_WIDE = "is_shade_layout_wide" + /** + * This key corresponds to a String value, representing the string form of [SensorLocation], + * which contains the information of the UDFPS location. + */ + const val KEY_UDFPS_LOCATION = "udfps_location" object Columns { /** String. Unique ID for the value. */ diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt index 47c5bda93c0e..70d17820a12c 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/FakeCustomizationProviderClient.kt @@ -108,10 +108,6 @@ class FakeCustomizationProviderClient( return flags.asStateFlow() } - override fun observeRuntimeValues(): Flow<Bundle> { - return runtimeValues.asStateFlow() - } - override suspend fun queryAffordances(): List<CustomizationProviderClient.Affordance> { return affordances.value } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt index a65415509d38..a6ed37ead7ae 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/composable/BouncerPredictiveBackTest.kt @@ -37,10 +37,10 @@ import androidx.compose.ui.semantics.SemanticsNode import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ObservableTransitionState import com.android.compose.animation.scene.Scale import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.UserAction import com.android.compose.animation.scene.UserActionResult import com.android.compose.animation.scene.isElement @@ -270,7 +270,7 @@ class BouncerPredictiveBackTest : SysuiTestCase() { override val userActions: Flow<Map<UserAction, UserActionResult>> = flowOf() @Composable - override fun SceneScope.Content(modifier: Modifier) { + override fun ContentScope.Content(modifier: Modifier) { Box(modifier = modifier, contentAlignment = Alignment.Center) { Text(text = "Fake Lockscreen") } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt index 47cba0723804..030233625027 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt @@ -367,8 +367,6 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot, LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to DeviceEntryRestrictionReason.AdaptiveAuthRequest, - LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to - DeviceEntryRestrictionReason.BouncerLockedOut, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to DeviceEntryRestrictionReason.SecurityTimeout, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to @@ -403,8 +401,6 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot, LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to DeviceEntryRestrictionReason.AdaptiveAuthRequest, - LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to - DeviceEntryRestrictionReason.BouncerLockedOut, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to DeviceEntryRestrictionReason.SecurityTimeout, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to @@ -440,8 +436,6 @@ class DeviceUnlockedInteractorTest : SysuiTestCase() { DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot, LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST to DeviceEntryRestrictionReason.AdaptiveAuthRequest, - LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT to - DeviceEntryRestrictionReason.BouncerLockedOut, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT to DeviceEntryRestrictionReason.SecurityTimeout, LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN to diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt index f66dee39166c..f2a6c11b872e 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt @@ -16,9 +16,11 @@ package com.android.systemui.education.data.repository +import android.content.Context import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.SysuiTestableContext import com.android.systemui.contextualeducation.GestureType.BACK import com.android.systemui.coroutines.collectLastValue import com.android.systemui.education.data.model.EduDeviceConnectionTime @@ -28,16 +30,21 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.google.common.truth.Truth.assertThat +import java.io.File import javax.inject.Provider import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Before +import org.junit.Ignore +import org.junit.Rule import org.junit.Test +import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) +@Ignore("b/384284415") class ContextualEducationRepositoryTest : SysuiTestCase() { private lateinit var underTest: UserContextualEducationRepository @@ -50,74 +57,83 @@ class ContextualEducationRepositoryTest : SysuiTestCase() { private val testUserId = 1111 private val secondTestUserId = 1112 + // For deleting any test files created after the test + @get:Rule val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build() + @Before fun setUp() { + // Create TestContext here because TemporaryFolder.create() is called in @Before. It is + // needed before calling TemporaryFolder.newFolder(). + val testContext = TestContext(context, tmpFolder.newFolder()) underTest = UserContextualEducationRepository( - context, + testContext, dsScopeProvider, kosmos.mockEduInputManager, - kosmos.testDispatcher, + kosmos.testDispatcher ) underTest.setUser(testUserId) } @Test - fun changeRetrievedValueForNewUser() = runTestAndClear { - // Update data for old user. - underTest.updateGestureEduModel(BACK) { it.copy(signalCount = 1) } - val model by testScope.collectLastValue(underTest.readGestureEduModelFlow(BACK)) - assertThat(model?.signalCount).isEqualTo(1) + fun changeRetrievedValueForNewUser() = + testScope.runTest { + // Update data for old user. + underTest.updateGestureEduModel(BACK) { it.copy(signalCount = 1) } + val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) + assertThat(model?.signalCount).isEqualTo(1) - // User is changed. - underTest.setUser(secondTestUserId) - // Assert count is 0 after user is changed. - assertThat(model?.signalCount).isEqualTo(0) - } + // User is changed. + underTest.setUser(secondTestUserId) + // Assert count is 0 after user is changed. + assertThat(model?.signalCount).isEqualTo(0) + } @Test - fun changeUserIdForNewUser() = runTestAndClear { - val model by testScope.collectLastValue(underTest.readGestureEduModelFlow(BACK)) - assertThat(model?.userId).isEqualTo(testUserId) - underTest.setUser(secondTestUserId) - assertThat(model?.userId).isEqualTo(secondTestUserId) - } + fun changeUserIdForNewUser() = + testScope.runTest { + val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) + assertThat(model?.userId).isEqualTo(testUserId) + underTest.setUser(secondTestUserId) + assertThat(model?.userId).isEqualTo(secondTestUserId) + } @Test - fun dataChangedOnUpdate() = runTestAndClear { - val newModel = - GestureEduModel( - signalCount = 2, - educationShownCount = 1, - lastShortcutTriggeredTime = kosmos.fakeEduClock.instant(), - lastEducationTime = kosmos.fakeEduClock.instant(), - usageSessionStartTime = kosmos.fakeEduClock.instant(), - userId = testUserId, - gestureType = BACK, - ) - underTest.updateGestureEduModel(BACK) { newModel } - val model by testScope.collectLastValue(underTest.readGestureEduModelFlow(BACK)) - assertThat(model).isEqualTo(newModel) - } + fun dataChangedOnUpdate() = + testScope.runTest { + val newModel = + GestureEduModel( + signalCount = 2, + educationShownCount = 1, + lastShortcutTriggeredTime = kosmos.fakeEduClock.instant(), + lastEducationTime = kosmos.fakeEduClock.instant(), + usageSessionStartTime = kosmos.fakeEduClock.instant(), + userId = testUserId, + gestureType = BACK + ) + underTest.updateGestureEduModel(BACK) { newModel } + val model by collectLastValue(underTest.readGestureEduModelFlow(BACK)) + assertThat(model).isEqualTo(newModel) + } @Test - fun eduDeviceConnectionTimeDataChangedOnUpdate() = runTestAndClear { - val newModel = - EduDeviceConnectionTime( - keyboardFirstConnectionTime = kosmos.fakeEduClock.instant(), - touchpadFirstConnectionTime = kosmos.fakeEduClock.instant(), - ) - underTest.updateEduDeviceConnectionTime { newModel } - val model by testScope.collectLastValue(underTest.readEduDeviceConnectionTime()) - assertThat(model).isEqualTo(newModel) - } - - private fun runTestAndClear(block: suspend () -> Unit) = + fun eduDeviceConnectionTimeDataChangedOnUpdate() = testScope.runTest { - try { - block() - } finally { - underTest.clear() - } + val newModel = + EduDeviceConnectionTime( + keyboardFirstConnectionTime = kosmos.fakeEduClock.instant(), + touchpadFirstConnectionTime = kosmos.fakeEduClock.instant(), + ) + underTest.updateEduDeviceConnectionTime { newModel } + val model by collectLastValue(underTest.readEduDeviceConnectionTime()) + assertThat(model).isEqualTo(newModel) + } + + /** Test context which allows overriding getFilesDir path */ + private class TestContext(context: Context, private val folder: File) : + SysuiTestableContext(context) { + override fun getFilesDir(): File { + return folder } + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt index bf49186a7f01..451ebf32c367 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt @@ -27,7 +27,7 @@ import android.provider.Settings.Secure.ZEN_DURATION_FOREVER import android.provider.Settings.Secure.ZEN_DURATION_PROMPT import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.settingslib.notification.modes.EnableZenModeDialog +import com.android.settingslib.notification.modes.EnableDndDialogFactory import com.android.settingslib.notification.modes.TestModeBuilder.MANUAL_DND import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable @@ -85,7 +85,7 @@ class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() { @Mock private lateinit var zenModeController: ZenModeController @Mock private lateinit var userTracker: UserTracker @Mock private lateinit var conditionUri: Uri - @Mock private lateinit var enableZenModeDialog: EnableZenModeDialog + @Mock private lateinit var mEnableDndDialogFactory: EnableDndDialogFactory @Captor private lateinit var spyZenMode: ArgumentCaptor<Int> @Captor private lateinit var spyConditionId: ArgumentCaptor<Uri?> @@ -105,7 +105,7 @@ class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() { testDispatcher, testScope.backgroundScope, conditionUri, - enableZenModeDialog, + mEnableDndDialogFactory, ) } @@ -322,7 +322,7 @@ class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() { testScope.runTest { val expandable: Expandable = mock() secureSettingsRepository.setInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_PROMPT) - whenever(enableZenModeDialog.createDialog()).thenReturn(mock()) + whenever(mEnableDndDialogFactory.createDialog()).thenReturn(mock()) collectLastValue(underTest.lockScreenState) runCurrent() @@ -344,7 +344,7 @@ class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() { whenever(zenModeController.isZenAvailable).thenReturn(true) whenever(zenModeController.zen).thenReturn(ZEN_MODE_OFF) settings.putInt(Settings.Secure.ZEN_DURATION, ZEN_DURATION_PROMPT) - whenever(enableZenModeDialog.createDialog()).thenReturn(mock()) + whenever(mEnableDndDialogFactory.createDialog()).thenReturn(mock()) collectLastValue(underTest.lockScreenState) runCurrent() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt index 605a5d261424..bafabe07d370 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt @@ -22,6 +22,7 @@ import android.platform.test.annotations.RequiresFlagsEnabled import android.platform.test.flag.junit.CheckFlagsRule import android.platform.test.flag.junit.DeviceFlagsValueProvider import android.view.IRemoteAnimationFinishedCallback +import android.view.RemoteAnimationTarget import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase @@ -39,11 +40,11 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq import org.mockito.Mock import org.mockito.Mockito.anyInt -import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations import org.mockito.kotlin.any +import org.mockito.kotlin.doAnswer import org.mockito.kotlin.mock import org.mockito.kotlin.whenever @@ -230,12 +231,15 @@ class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { @Test fun remoteAnimationInstantlyFinished_ifDismissTransitionNotStarted() { val mockedCallback = mock<IRemoteAnimationFinishedCallback>() - whenever(keyguardDismissTransitionInteractor.startDismissKeyguardTransition(any())) - .thenReturn(false) + + // Call the onAlreadyGone callback immediately. + doAnswer { invocation -> (invocation.getArgument(1) as (() -> Unit)).invoke() } + .whenever(keyguardDismissTransitionInteractor) + .startDismissKeyguardTransition(any(), any()) underTest.onKeyguardGoingAwayRemoteAnimationStart( transit = 0, - apps = emptyArray(), + apps = arrayOf(mock<RemoteAnimationTarget>()), wallpapers = emptyArray(), nonApps = emptyArray(), finishedCallback = mockedCallback, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepositoryTest.kt index ec0773f79328..5a350435002f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepositoryTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSColumnsRepositoryTest.kt @@ -24,7 +24,6 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testCase import com.android.systemui.kosmos.testScope import com.android.systemui.res.R -import com.android.systemui.shade.data.repository.fakeShadeRepository import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest @@ -35,7 +34,17 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class QSColumnsRepositoryTest : SysuiTestCase() { - private val kosmos = testKosmos() + private val kosmos = + testKosmos().apply { + testCase.context.orCreateTestableResources.addOverride( + R.integer.quick_settings_dual_shade_num_columns, + 2, + ) + testCase.context.orCreateTestableResources.addOverride( + R.integer.quick_settings_split_shade_num_columns, + 3, + ) + } private lateinit var underTest: QSColumnsRepository @Before @@ -63,7 +72,7 @@ class QSColumnsRepositoryTest : SysuiTestCase() { testScope.runTest { val latest by collectLastValue(underTest.dualShadeColumns) - assertThat(latest).isEqualTo(4) + assertThat(latest).isEqualTo(2) } } @@ -72,9 +81,8 @@ class QSColumnsRepositoryTest : SysuiTestCase() { with(kosmos) { testScope.runTest { val latest by collectLastValue(underTest.splitShadeColumns) - fakeShadeRepository.setShadeLayoutWide(true) - assertThat(latest).isEqualTo(4) + assertThat(latest).isEqualTo(3) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt index 79556baed067..fecd8c3cacca 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt @@ -26,11 +26,9 @@ import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.internal.logging.MetricsLogger -import com.android.systemui.Flags import com.android.systemui.Flags.FLAG_SCENE_CONTAINER import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake -import com.android.systemui.flags.setFlagValue import com.android.systemui.keyguard.KeyguardWmStateRefactor import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -42,7 +40,6 @@ import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tiles.dialog.InternetDialogManager import com.android.systemui.qs.tiles.dialog.WifiStateWorker import com.android.systemui.res.R -import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.shared.flag.DualShade import com.android.systemui.statusbar.connectivity.AccessPointController import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun @@ -65,6 +62,7 @@ import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -150,11 +148,18 @@ class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() { ) underTest.initialize() + underTest.setListening(Object(), true) looper.processAllMessages() } + @After + fun tearDown() { + underTest.destroy() + looper.processAllMessages() + } + @Test fun noDefaultConnection_noNetworkAvailable() = testScope.runTest { @@ -272,33 +277,37 @@ class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() { underTest.click(null) looper.processAllMessages() - verify(dialogManager, times(1)).create( - aboveStatusBar = true, - accessPointController.canConfigMobileData(), - accessPointController.canConfigWifi(), - null, - ) + verify(dialogManager, times(1)) + .create( + aboveStatusBar = true, + accessPointController.canConfigMobileData(), + accessPointController.canConfigWifi(), + null, + ) } @Test @EnableFlags( - value = [ - QsDetailedView.FLAG_NAME, - FLAG_SCENE_CONTAINER, - KeyguardWmStateRefactor.FLAG_NAME, - NotificationThrottleHun.FLAG_NAME, - DualShade.FLAG_NAME] + value = + [ + QsDetailedView.FLAG_NAME, + FLAG_SCENE_CONTAINER, + KeyguardWmStateRefactor.FLAG_NAME, + NotificationThrottleHun.FLAG_NAME, + DualShade.FLAG_NAME, + ] ) fun click_withQsDetailedViewEnabled() { underTest.click(null) looper.processAllMessages() - verify(dialogManager, times(0)).create( - aboveStatusBar = true, - accessPointController.canConfigMobileData(), - accessPointController.canConfigWifi(), - null, - ) + verify(dialogManager, times(0)) + .create( + aboveStatusBar = true, + accessPointController.canConfigMobileData(), + accessPointController.canConfigWifi(), + null, + ) } companion object { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt index 9173ac969324..f005375a2ef9 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt @@ -48,6 +48,7 @@ import com.android.systemui.res.R import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate +import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger import com.android.systemui.testKosmos import com.android.systemui.util.mockito.any import com.android.systemui.util.settings.FakeSettings @@ -123,7 +124,12 @@ class ModesTileTest : SysuiTestCase() { ) userActionInteractor = - ModesTileUserActionInteractor(inputHandler, dialogDelegate, kosmos.zenModeInteractor) + ModesTileUserActionInteractor( + inputHandler, + dialogDelegate, + kosmos.zenModeInteractor, + kosmos.modesDialogEventLogger, + ) underTest = ModesTile( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt index c7da03dbbf30..497e33536b7f 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/RecordIssueTileTest.kt @@ -46,6 +46,7 @@ import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import java.util.concurrent.Executors +import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -123,6 +124,12 @@ class RecordIssueTileTest : SysuiTestCase() { ) } + @After + fun teardown() { + tile.destroy() + testableLooper.processAllMessages() + } + @Test fun qsTileUi_shouldLookCorrect_whenInactive() { whenever(issueRecordingState.isRecording).thenReturn(false) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt index 44e6b4d2d0f6..029a2f91a4ba 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt @@ -58,7 +58,9 @@ class ModesTileDataInteractorTest : SysuiTestCase() { private val dispatcher = kosmos.testDispatcher private val zenModeRepository = kosmos.fakeZenModeRepository - private val underTest = ModesTileDataInteractor(context, kosmos.zenModeInteractor, dispatcher) + private val underTest by lazy { + ModesTileDataInteractor(context, kosmos.zenModeInteractor, dispatcher) + } @Before fun setUp() { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt index c8b3aba9b846..89b8e9171076 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt @@ -38,6 +38,7 @@ import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.statusbar.policy.data.repository.zenModeRepository import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.mockModesDialogDelegate +import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -60,7 +61,12 @@ class ModesTileUserActionInteractorTest : SysuiTestCase() { private val zenModeInteractor = kosmos.zenModeInteractor private val underTest = - ModesTileUserActionInteractor(inputHandler, mockDialogDelegate, zenModeInteractor) + ModesTileUserActionInteractor( + inputHandler, + mockDialogDelegate, + zenModeInteractor, + kosmos.modesDialogEventLogger, + ) @Test fun handleClick_active_showsDialog() = runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 51f056aa18da..cb7267b2c34c 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -1508,10 +1508,8 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test - fun collectFalsingSignals_screenOnAndOff_aodUnavailable() = + fun collectFalsingSignals_screenOnAndOff() = testScope.runTest { - kosmos.fakeKeyguardRepository.setAodAvailable(false) - runCurrent() prepareState( initialSceneKey = Scenes.Lockscreen, authenticationMethod = AuthenticationMethodModel.Pin, @@ -1556,53 +1554,6 @@ class SceneContainerStartableTest : SysuiTestCase() { } @Test - fun collectFalsingSignals_screenOnAndOff_aodAvailable() = - testScope.runTest { - kosmos.fakeKeyguardRepository.setAodAvailable(true) - runCurrent() - prepareState( - initialSceneKey = Scenes.Lockscreen, - authenticationMethod = AuthenticationMethodModel.Pin, - isDeviceUnlocked = false, - ) - underTest.start() - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - - powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON) - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - - powerInteractor.setAsleepForTest() - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - - powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_TAP) - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - - powerInteractor.setAsleepForTest() - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - - powerInteractor.setAwakeForTest(reason = PowerManager.WAKE_REASON_POWER_BUTTON) - runCurrent() - verify(falsingCollector, never()).onScreenTurningOn() - verify(falsingCollector, never()).onScreenOnFromTouch() - verify(falsingCollector, never()).onScreenOff() - } - - @Test fun collectFalsingSignals_bouncerVisibility() = testScope.runTest { prepareState( diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/customization/data/SensorLocationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/customization/data/SensorLocationTest.kt new file mode 100644 index 000000000000..526fd45533c7 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/customization/data/SensorLocationTest.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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.shared.customization.data + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class SensorLocationTest : SysuiTestCase() { + + @Test + fun encodeAndDecode() { + val sensorLocation = SensorLocation(640, 2068, 117, 0.75f) + + assertThat(SensorLocation.decode(sensorLocation.encode())).isEqualTo(sensorLocation) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt index ac3089d9286b..b0af8b180cce 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt @@ -30,10 +30,12 @@ import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.activityStarter import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.core.StatusBarConnectedDisplays +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel @@ -64,7 +66,7 @@ class CallChipViewModelTest : SysuiTestCase() { .thenReturn(chipBackgroundView) } - private val underTest = kosmos.callChipViewModel + private val underTest by lazy { kosmos.callChipViewModel } @Test fun chip_noCall_isHidden() = @@ -219,28 +221,94 @@ class CallChipViewModelTest : SysuiTestCase() { } @Test - fun chip_positiveStartTime_colorsAreThemed() = + fun chip_positiveStartTime_notPromoted_colorsAreThemed() = testScope.runTest { val latest by collectLastValue(underTest.chip) - repo.setOngoingCallState(inCallModel(startTimeMs = 1000)) + repo.setOngoingCallState(inCallModel(startTimeMs = 1000, promotedContent = null)) assertThat((latest as OngoingActivityChipModel.Shown).colors) .isEqualTo(ColorsModel.Themed) } @Test - fun chip_zeroStartTime_colorsAreThemed() = + fun chip_zeroStartTime_notPromoted_colorsAreThemed() = testScope.runTest { val latest by collectLastValue(underTest.chip) - repo.setOngoingCallState(inCallModel(startTimeMs = 0)) + repo.setOngoingCallState(inCallModel(startTimeMs = 0, promotedContent = null)) + + assertThat((latest as OngoingActivityChipModel.Shown).colors) + .isEqualTo(ColorsModel.Themed) + } + + @Test + @DisableFlags(StatusBarNotifChips.FLAG_NAME) + fun chip_positiveStartTime_promoted_notifChipsFlagOff_colorsAreThemed() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + repo.setOngoingCallState( + inCallModel(startTimeMs = 1000, promotedContent = PROMOTED_CONTENT_WITH_COLOR) + ) assertThat((latest as OngoingActivityChipModel.Shown).colors) .isEqualTo(ColorsModel.Themed) } @Test + @DisableFlags(StatusBarNotifChips.FLAG_NAME) + fun chip_zeroStartTime_promoted_notifChipsFlagOff_colorsAreThemed() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + repo.setOngoingCallState( + inCallModel(startTimeMs = 0, promotedContent = PROMOTED_CONTENT_WITH_COLOR) + ) + + assertThat((latest as OngoingActivityChipModel.Shown).colors) + .isEqualTo(ColorsModel.Themed) + } + + @Test + @EnableFlags(StatusBarNotifChips.FLAG_NAME) + fun chip_positiveStartTime_promoted_notifChipsFlagOn_colorsAreCustom() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + repo.setOngoingCallState( + inCallModel(startTimeMs = 1000, promotedContent = PROMOTED_CONTENT_WITH_COLOR) + ) + + assertThat((latest as OngoingActivityChipModel.Shown).colors) + .isEqualTo( + ColorsModel.Custom( + backgroundColorInt = PROMOTED_BACKGROUND_COLOR, + primaryTextColorInt = PROMOTED_PRIMARY_TEXT_COLOR, + ) + ) + } + + @Test + @EnableFlags(StatusBarNotifChips.FLAG_NAME) + fun chip_zeroStartTime_promoted_notifChipsFlagOff_colorsAreCustom() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + repo.setOngoingCallState( + inCallModel(startTimeMs = 0, promotedContent = PROMOTED_CONTENT_WITH_COLOR) + ) + + assertThat((latest as OngoingActivityChipModel.Shown).colors) + .isEqualTo( + ColorsModel.Custom( + backgroundColorInt = PROMOTED_BACKGROUND_COLOR, + primaryTextColorInt = PROMOTED_PRIMARY_TEXT_COLOR, + ) + ) + } + + @Test fun chip_resetsCorrectly() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -275,7 +343,7 @@ class CallChipViewModelTest : SysuiTestCase() { repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = null)) - assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull() + assertThat((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy).isNull() } @Test @@ -285,7 +353,7 @@ class CallChipViewModelTest : SysuiTestCase() { val pendingIntent = mock<PendingIntent>() repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = pendingIntent)) - val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener + val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListenerLegacy assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -302,7 +370,8 @@ class CallChipViewModelTest : SysuiTestCase() { val pendingIntent = mock<PendingIntent>() repo.setOngoingCallState(inCallModel(startTimeMs = 0, intent = pendingIntent)) - val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener + val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListenerLegacy + assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -319,5 +388,19 @@ class CallChipViewModelTest : SysuiTestCase() { } else { mock<StatusBarIconView>() } + + private val PROMOTED_CONTENT_WITH_COLOR = + PromotedNotificationContentModel.Builder("notif") + .apply { + this.colors = + PromotedNotificationContentModel.Colors( + backgroundColor = PROMOTED_BACKGROUND_COLOR, + primaryTextColor = PROMOTED_PRIMARY_TEXT_COLOR, + ) + } + .build() + + private const val PROMOTED_BACKGROUND_COLOR = 65 + private const val PROMOTED_PRIMARY_TEXT_COLOR = 98 } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt index c511c433d92d..fcf8c834dc12 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel import android.content.DialogInterface +import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -25,6 +26,7 @@ import com.android.internal.jank.Cuj import com.android.systemui.Flags.FLAG_STATUS_BAR_SHOW_AUDIO_ONLY_PROJECTION_CHIP import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogCuj +import com.android.systemui.animation.Expandable import com.android.systemui.animation.mockDialogTransitionAnimator import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon @@ -46,8 +48,10 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.statusbar.policy.CastDevice import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat @@ -84,6 +88,8 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest = kosmos.castToOtherDeviceChipViewModel @@ -263,7 +269,13 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { // WHEN the stop action on the dialog is clicked val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockScreenCastDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockScreenCastDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden... @@ -296,7 +308,13 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { // WHEN the stop action on the dialog is clicked val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockGenericCastDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockGenericCastDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden... @@ -416,13 +434,14 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_projectionStateEntireScreen_clickListenerShowsScreenCastDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -431,6 +450,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_projectionStateSingleTask_clickListenerShowsScreenCastDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -442,7 +462,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { createTask(taskId = 1), ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -451,6 +471,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_routerStateCasting_clickListenerShowsGenericCastDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -466,7 +487,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { ) ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -480,13 +501,14 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_projectionStateCasting_clickListenerHasCuj() = testScope.runTest { val latest by collectLastValue(underTest.chip) mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) clickListener!!.onClick(chipView) val cujCaptor = argumentCaptor<DialogCuj>() @@ -499,6 +521,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_routerStateCasting_clickListenerHasCuj() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -514,7 +537,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { ) ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) clickListener!!.onClick(chipView) val cujCaptor = argumentCaptor<DialogCuj>() @@ -525,4 +548,103 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() { .isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP) assertThat(cujCaptor.firstValue.tag).contains("Cast") } + + @Test + @EnableFlags(StatusBarChipsModernization.FLAG_NAME) + fun chip_routerStateCasting_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + mediaRouterRepo.castDevices.value = + listOf( + CastDevice( + state = CastDevice.CastState.Connected, + id = "id", + name = "name", + description = "desc", + origin = CastDevice.CastOrigin.MediaRouter, + ) + ) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags(StatusBarChipsModernization.FLAG_NAME) + fun chip_projectionStateCasting_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_projectionStateEntireScreen_clickBehaviorShowsScreenCastDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockScreenCastDialog), any(), anyBoolean()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_projectionStateSingleTask_clickBehaviorShowsScreenCastDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.SingleTask( + CAST_TO_OTHER_DEVICES_PACKAGE, + hostDeviceName = null, + createTask(taskId = 1), + ) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockScreenCastDialog), any(), anyBoolean()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_routerStateCasting_clickBehaviorShowsGenericCastDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + mediaRouterRepo.castDevices.value = + listOf( + CastDevice( + state = CastDevice.CastState.Connected, + id = "id", + name = "name", + description = "desc", + origin = CastDevice.CastOrigin.MediaRouter, + ) + ) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockGenericCastDialog), any(), anyBoolean()) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt index ee4a52d35d68..e89c929a5827 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractorTest.kt @@ -36,6 +36,7 @@ import com.android.systemui.statusbar.notification.data.repository.ActiveNotific import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel +import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.testKosmos import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat @@ -178,6 +179,37 @@ class StatusBarNotificationChipsInteractorTest : SysuiTestCase() { assertThat(latest!![1].statusBarChipIconView).isEqualTo(secondIcon) } + /** Regression test for b/388521980. */ + @Test + @EnableFlags(StatusBarNotifChips.FLAG_NAME) + fun notificationChips_callNotifIsAlsoPromoted_callNotifExcluded() = + kosmos.runTest { + val latest by collectLastValue(underTest.notificationChips) + + setNotifs( + listOf( + activeNotificationModel( + key = "promotedNormal", + statusBarChipIcon = mock(), + promotedContent = + PromotedNotificationContentModel.Builder("promotedNormal").build(), + callType = CallType.None, + ), + activeNotificationModel( + key = "promotedCall", + statusBarChipIcon = mock(), + promotedContent = + PromotedNotificationContentModel.Builder("promotedCall").build(), + callType = CallType.Ongoing, + ), + ) + ) + + // Verify the promoted call notification is not included + assertThat(latest).hasSize(1) + assertThat(latest!![0].key).isEqualTo("promotedNormal") + } + @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) fun notificationChips_notifUpdatesGoThrough() = diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt index 902db5e10589..eec23d3ffb1a 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModelTest.kt @@ -650,7 +650,7 @@ class NotifChipsViewModelTest : SysuiTestCase() { ) val chip = latest!![0] - chip.onClickListener!!.onClick(mock<View>()) + chip.onClickListenerLegacy!!.onClick(mock<View>()) assertThat(latestChipTap).isEqualTo("clickTest") } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt index 48d8add6b33a..1f82dcd9c308 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt @@ -17,12 +17,15 @@ package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel import android.content.DialogInterface +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.jank.Cuj import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogCuj +import com.android.systemui.animation.Expandable import com.android.systemui.animation.mockDialogTransitionAnimator import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue @@ -41,8 +44,10 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.testKosmos import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat @@ -77,6 +82,8 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest = kosmos.screenRecordChipViewModel @@ -106,7 +113,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Countdown::class.java) assertThat((latest as OngoingActivityChipModel.Shown).icon).isNull() - assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull() + assertThat((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy).isNull() } // The millis we typically get from [ScreenRecordRepository] are around 2995, 1995, and 995. @@ -177,7 +184,13 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { // WHEN the stop action on the dialog is clicked val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockSystemUIDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN both the screen record chip and the share-to-app chip are immediately hidden... @@ -263,13 +276,14 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_notProjecting_clickListenerShowsDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -279,6 +293,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_projectingEntireScreen_clickListenerShowsDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -286,7 +301,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.EntireScreen("host.package") - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -296,6 +311,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_projectingSingleTask_clickListenerShowsDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -307,7 +323,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { FakeActivityTaskManager.createTask(taskId = 1), ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -317,22 +333,85 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() { } @Test - fun chip_clickListenerHasCuj() = + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) + fun chip_clickListenerHasCujLegacy() = testScope.runTest { val latest by collectLastValue(underTest.chip) screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.EntireScreen("host.package") - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) clickListener!!.onClick(chipView) val cujCaptor = argumentCaptor<DialogCuj>() verify(kosmos.mockDialogTransitionAnimator) .showFromView(any(), any(), cujCaptor.capture(), anyBoolean()) - assertThat(cujCaptor.firstValue.cujType) .isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP) assertThat(cujCaptor.firstValue.tag).contains("Screen record") } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_recordingState_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java) + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_notProjecting_expandActionBehaviorShowsDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + + expandAction.onClick(mockExpandable) + verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_projectingEntireScreen_expandActionBehaviorShowsDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + + expandAction.onClick(mockExpandable) + verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_projectingSingleTask_expandActionBehaviorShowsDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.SingleTask( + "host.package", + hostDeviceName = null, + FakeActivityTaskManager.createTask(taskId = 1), + ) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + + expandAction.onClick(mockExpandable) + verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean()) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt index b3dec2eaa1c6..36fc5aa16407 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel import android.content.DialogInterface +import android.platform.test.annotations.DisableFlags import android.platform.test.annotations.EnableFlags import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -25,6 +26,7 @@ import com.android.internal.jank.Cuj import com.android.systemui.Flags.FLAG_STATUS_BAR_SHOW_AUDIO_ONLY_PROJECTION_CHIP import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogCuj +import com.android.systemui.animation.Expandable import com.android.systemui.animation.mockDialogTransitionAnimator import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon @@ -45,8 +47,10 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.util.time.fakeSystemClock import com.google.common.truth.Truth.assertThat import kotlin.test.Test @@ -81,6 +85,8 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest = kosmos.shareToAppChipViewModel @@ -215,7 +221,13 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { // WHEN the stop action on the dialog is clicked val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockScreenShareDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockScreenShareDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden... @@ -268,13 +280,14 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { @Test @EnableFlags(FLAG_STATUS_BAR_SHOW_AUDIO_ONLY_PROJECTION_CHIP) + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_noScreen_clickListenerShowsGenericShareDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.NoScreen(NORMAL_PACKAGE) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -288,13 +301,14 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_entireScreen_clickListenerShowsScreenShareDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -308,6 +322,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_singleTask_clickListenerShowsScreenShareDialog() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -318,7 +333,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { createTask(taskId = 1), ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) assertThat(clickListener).isNotNull() clickListener!!.onClick(chipView) @@ -332,6 +347,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun chip_clickListenerHasCuj() = testScope.runTest { val latest by collectLastValue(underTest.chip) @@ -342,7 +358,7 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { createTask(taskId = 1), ) - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) + val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) clickListener!!.onClick(chipView) val cujCaptor = argumentCaptor<DialogCuj>() @@ -353,4 +369,101 @@ class ShareToAppChipViewModelTest : SysuiTestCase() { .isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP) assertThat(cujCaptor.firstValue.tag).contains("Share") } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_noScreen_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.NoScreen(NORMAL_PACKAGE) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_entireScreen_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_singleTask_hasClickBehavior() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.SingleTask( + NORMAL_PACKAGE, + hostDeviceName = null, + createTask(taskId = 1), + ) + + assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior) + .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java) + } + + @Test + @EnableFlags( + FLAG_STATUS_BAR_SHOW_AUDIO_ONLY_PROJECTION_CHIP, + StatusBarRootModernization.FLAG_NAME, + StatusBarChipsModernization.FLAG_NAME, + ) + fun chip_noScreen_clickBehaviorShowsGenericShareDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.NoScreen(NORMAL_PACKAGE) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockGenericShareDialog), any(), any()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_entireScreen_clickBehaviorShowsScreenShareDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockScreenShareDialog), any(), any()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun chip_singleTask_clickBehaviorShowsScreenShareDialog() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + mediaProjectionRepo.mediaProjectionState.value = + MediaProjectionState.Projecting.SingleTask( + NORMAL_PACKAGE, + hostDeviceName = null, + createTask(taskId = 1), + ) + + val expandAction = + ((latest as OngoingActivityChipModel.Shown).clickBehavior + as OngoingActivityChipModel.ClickBehavior.ExpandAction) + expandAction.onClick(mockExpandable) + + verify(kosmos.mockDialogTransitionAnimator) + .show(eq(mockScreenShareDialog), any(), any()) + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt index 8d4c68de8c79..d099e70c9bc5 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt @@ -57,7 +57,8 @@ class ChipTransitionHelperTest : SysuiTestCase() { icon = createIcon(R.drawable.ic_cake), colors = ColorsModel.Themed, startTimeMs = 100L, - onClickListener = null, + onClickListenerLegacy = null, + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) inputChipFlow.value = newChip @@ -68,7 +69,8 @@ class ChipTransitionHelperTest : SysuiTestCase() { OngoingActivityChipModel.Shown.IconOnly( icon = createIcon(R.drawable.ic_hotspot), colors = ColorsModel.Themed, - onClickListener = null, + onClickListenerLegacy = null, + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) inputChipFlow.value = newerChip @@ -89,7 +91,8 @@ class ChipTransitionHelperTest : SysuiTestCase() { icon = createIcon(R.drawable.ic_cake), colors = ColorsModel.Themed, startTimeMs = 100L, - onClickListener = null, + onClickListenerLegacy = null, + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) inputChipFlow.value = shownChip @@ -129,7 +132,8 @@ class ChipTransitionHelperTest : SysuiTestCase() { icon = createIcon(R.drawable.ic_cake), colors = ColorsModel.Themed, startTimeMs = 100L, - onClickListener = null, + onClickListenerLegacy = null, + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) inputChipFlow.value = shownChip diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt index e3510f5ce280..fc3af11c30b3 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.chips.ui.viewmodel +import android.platform.test.annotations.DisableFlags +import android.platform.test.annotations.EnableFlags import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest @@ -23,14 +25,19 @@ import com.android.internal.jank.Cuj import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator +import com.android.systemui.animation.Expandable import com.android.systemui.log.logcatLogBuffer import com.android.systemui.res.R import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer +import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickCallback import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener +import com.android.systemui.statusbar.core.StatusBarRootModernization import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import kotlin.test.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.kotlin.any import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.verify @@ -53,8 +60,11 @@ class OngoingActivityChipViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } @Test + @DisableFlags(StatusBarChipsModernization.FLAG_NAME) fun createDialogLaunchOnClickListener_showsDialogOnClick() { val cuj = DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Test") val clickListener = @@ -68,11 +78,23 @@ class OngoingActivityChipViewModelTest : SysuiTestCase() { clickListener.onClick(chipView) verify(dialogTransitionAnimator) - .showFromView( - eq(mockSystemUIDialog), - eq(chipBackgroundView), - eq(cuj), - anyBoolean(), + .showFromView(eq(mockSystemUIDialog), eq(chipBackgroundView), eq(cuj), anyBoolean()) + } + + @Test + @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME) + fun createDialogLaunchOnClickCallback_showsDialogOnClick() { + val cuj = DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Test") + val clickCallback = + createDialogLaunchOnClickCallback( + dialogDelegate, + dialogTransitionAnimator, + cuj, + logcatLogBuffer("OngoingActivityChipViewModelTest"), + "tag", ) + + clickCallback.invoke(mockExpandable) + verify(dialogTransitionAnimator).show(eq(mockSystemUIDialog), any(), anyBoolean()) } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt index 42358cce59a2..a4b6a841d61b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt @@ -26,6 +26,7 @@ import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos @@ -44,6 +45,7 @@ import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.core.StatusBarConnectedDisplays import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel @@ -91,6 +93,8 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest = kosmos.ongoingActivityChipsViewModel @@ -294,7 +298,13 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { // WHEN screen record gets stopped via dialog val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockSystemUIDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden with no animation @@ -315,7 +325,13 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { // WHEN media projection gets stopped via dialog val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockSystemUIDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden with no animation @@ -330,6 +346,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { fun getStopActionFromDialog( latest: OngoingActivityChipModel?, chipView: View, + expandable: Expandable, dialog: SystemUIDialog, kosmos: Kosmos, ): DialogInterface.OnClickListener { @@ -349,9 +366,17 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { .create(any<SystemUIDialog.Delegate>()) whenever(kosmos.packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>())) .thenThrow(PackageManager.NameNotFoundException()) - // Click the chip so that we open the dialog and we fill in [dialogStopAction] - val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener) - clickListener!!.onClick(chipView) + + if (StatusBarChipsModernization.isEnabled) { + val clickBehavior = (latest as OngoingActivityChipModel.Shown).clickBehavior + (clickBehavior as OngoingActivityChipModel.ClickBehavior.ExpandAction).onClick( + expandable + ) + } else { + val clickListener = + ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy) + clickListener!!.onClick(chipView) + } return dialogStopAction } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt index 0f42f29e76ee..28f360108e50 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsWithNotifsViewModelTest.kt @@ -25,6 +25,7 @@ import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.animation.Expandable import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.useUnconfinedTestDispatcher @@ -104,6 +105,8 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() { ) .thenReturn(chipBackgroundView) } + private val mockExpandable: Expandable = + mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) } private val underTest by lazy { kosmos.ongoingActivityChipsViewModel } @@ -679,7 +682,13 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() { // WHEN screen record gets stopped via dialog val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockSystemUIDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden with no animation @@ -700,7 +709,13 @@ class OngoingActivityChipsWithNotifsViewModelTest : SysuiTestCase() { // WHEN media projection gets stopped via dialog val dialogStopAction = - getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos) + getStopActionFromDialog( + latest, + chipView, + mockExpandable, + mockSystemUIDialog, + kosmos, + ) dialogStopAction.onClick(mock<DialogInterface>(), 0) // THEN the chip is immediately hidden with no animation diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java index 657fffb1875d..7b120947b1d6 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java @@ -16,17 +16,21 @@ package com.android.systemui.statusbar.notification.collection.coordinator; -import static com.android.systemui.flags.SceneContainerFlagParameterizationKt.parameterizeSceneContainerFlag; +import static android.platform.test.flag.junit.FlagsParameterization.allCombinationsOf; import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; + +import static org.junit.Assume.assumeFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -48,6 +52,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.BrokenWithSceneContainer; import com.android.systemui.flags.DisableSceneContainer; import com.android.systemui.flags.EnableSceneContainer; +import com.android.systemui.flags.SceneContainerFlagParameterizationKt; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.shared.model.KeyguardState; import com.android.systemui.keyguard.shared.model.TransitionState; @@ -86,9 +91,11 @@ import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; import java.util.List; +import java.util.Set; import kotlinx.coroutines.flow.MutableStateFlow; import kotlinx.coroutines.test.TestScope; + import platform.test.runner.parameterized.ParameterizedAndroidJunit4; import platform.test.runner.parameterized.Parameters; @@ -99,7 +106,8 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { @Parameters(name = "{0}") public static List<FlagsParameterization> getParams() { - return parameterizeSceneContainerFlag(); + return SceneContainerFlagParameterizationKt + .andSceneContainer(allCombinationsOf(Flags.FLAG_STABILIZE_HEADS_UP_GROUP)); } private VisualStabilityCoordinator mCoordinator; @@ -122,7 +130,8 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this); private FakeSystemClock mFakeSystemClock = new FakeSystemClock(); - private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock); + private FakeExecutor mFakeBackgroundExecutor = new FakeExecutor(mFakeSystemClock); + private FakeExecutor mFakeMainExecutor = new FakeExecutor(mFakeSystemClock); private final TestScope mTestScope = mKosmos.getTestScope(); private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope()); @@ -147,7 +156,8 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { mShadeAnimationInteractor = new ShadeAnimationInteractorLegacyImpl( new ShadeAnimationRepository(), mShadeRepository); mCoordinator = new VisualStabilityCoordinator( - mFakeExecutor, + mFakeBackgroundExecutor, + mFakeMainExecutor, mDumpManager, mHeadsUpManager, mShadeAnimationInteractor, @@ -417,8 +427,8 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry)); // WHEN the timeout for the temporarily allow section reordering runnable is finsihed - mFakeExecutor.advanceClockToNext(); - mFakeExecutor.runNextReady(); + mFakeBackgroundExecutor.advanceClockToNext(); + mFakeBackgroundExecutor.runNextReady(); // THEN section changes aren't allowed anymore assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry)); @@ -701,6 +711,212 @@ public class VisualStabilityCoordinatorTest extends SysuiTestCase { assertFalse(mNotifStabilityManager.isGroupPruneAllowed(mGroupEntry)); } + @Test + public void everyChangeAllowed_onReorderingEnabled_legacy() { + assumeFalse(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // THEN + assertThat(mNotifStabilityManager.isEveryChangeAllowed()).isTrue(); + assertThat(mNotifStabilityManager.isGroupChangeAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isGroupPruneAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isSectionChangeAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(any())).isTrue(); + } + + @Test + public void everyChangeAllowed_noActiveHeadsUpGroup_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - empty heads-up-group keys + mCoordinator.setHeadsUpGroupKeys(Set.of()); + + // THEN + assertThat(mNotifStabilityManager.isEveryChangeAllowed()).isTrue(); + assertThat(mNotifStabilityManager.isGroupChangeAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isGroupPruneAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isSectionChangeAllowed(any())).isTrue(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(any())).isTrue(); + } + + @Test + public void everyChangeDisallowed_activeHeadsUpGroup_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + mCoordinator.setHeadsUpGroupKeys(Set.of("heads_up_group_key")); + + // THEN + assertThat(mNotifStabilityManager.isEveryChangeAllowed()).isFalse(); + } + + @Test + public void nonHeadsUpGroup_changesAllowed_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + String headsUpGroupKey = "heads_up_group_key"; + mCoordinator.setHeadsUpGroupKeys(Set.of(headsUpGroupKey)); + when(mHeadsUpManager.isHeadsUpEntry(headsUpGroupKey)).thenReturn(true); + + // GIVEN - HUN Group Summary + final NotificationEntry nonHeadsUpGroupSummary = mock(NotificationEntry.class); + when(nonHeadsUpGroupSummary.getKey()).thenReturn("non_heads_up_group_key"); + when(nonHeadsUpGroupSummary.isSummaryWithChildren()).thenReturn(true); + final GroupEntry nonHeadsUpGroupEntry = mock(GroupEntry.class); + when(nonHeadsUpGroupEntry.getSummary()).thenReturn(nonHeadsUpGroupSummary); + when(nonHeadsUpGroupEntry.getRepresentativeEntry()).thenReturn(nonHeadsUpGroupSummary); + + // THEN + assertThat(mNotifStabilityManager.isGroupPruneAllowed(nonHeadsUpGroupEntry)).isTrue(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(nonHeadsUpGroupEntry)).isTrue(); + } + + @Test + public void headsUpGroup_changesDisallowed_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + final String headsUpGroupKey = "heads_up_group_key"; + mCoordinator.setHeadsUpGroupKeys(Set.of(headsUpGroupKey)); + when(mHeadsUpManager.isHeadsUpEntry(headsUpGroupKey)).thenReturn(true); + + // GIVEN - HUN Group + final NotificationEntry headsUpGroupSummary = mock(NotificationEntry.class); + when(headsUpGroupSummary.rowIsChildInGroup()).thenReturn(false); + when(headsUpGroupSummary.getKey()).thenReturn(headsUpGroupKey); + when(headsUpGroupSummary.isSummaryWithChildren()).thenReturn(true); + + final GroupEntry headsUpGroupEntry = mock(GroupEntry.class); + when(headsUpGroupEntry.getSummary()).thenReturn(headsUpGroupSummary); + when(headsUpGroupEntry.getRepresentativeEntry()).thenReturn(headsUpGroupSummary); + + when(headsUpGroupSummary.getParent()).thenReturn(headsUpGroupEntry); + + // GIVEN - HUN is in visible location + when(mVisibilityLocationProvider.isInVisibleLocation(headsUpGroupSummary)).thenReturn(true); + + // THEN + assertThat(mNotifStabilityManager.isGroupPruneAllowed(headsUpGroupEntry)).isFalse(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(headsUpGroupEntry)).isFalse(); + } + + @Test + public void headsUpGroupSummaries_changesDisallowed_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + final String headsUpGroupKey = "heads_up_group_key"; + mCoordinator.setHeadsUpGroupKeys(Set.of(headsUpGroupKey)); + when(mHeadsUpManager.isHeadsUpEntry(headsUpGroupKey)).thenReturn(true); + + // GIVEN - HUN Group + final NotificationEntry headsUpGroupSummary = mock(NotificationEntry.class); + when(headsUpGroupSummary.rowIsChildInGroup()).thenReturn(false); + when(headsUpGroupSummary.getKey()).thenReturn(headsUpGroupKey); + when(headsUpGroupSummary.isSummaryWithChildren()).thenReturn(true); + + final GroupEntry headsUpGroupEntry = mock(GroupEntry.class); + when(headsUpGroupEntry.getSummary()).thenReturn(headsUpGroupSummary); + when(headsUpGroupEntry.getRepresentativeEntry()).thenReturn(headsUpGroupSummary); + + when(headsUpGroupSummary.getParent()).thenReturn(headsUpGroupEntry); + + // GIVEN - HUN is in visible location + when(mVisibilityLocationProvider.isInVisibleLocation(headsUpGroupSummary)).thenReturn(true); + + // THEN + assertThat(mNotifStabilityManager.isGroupChangeAllowed(headsUpGroupSummary)).isFalse(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(headsUpGroupSummary)).isFalse(); + assertThat(mNotifStabilityManager.isSectionChangeAllowed(headsUpGroupSummary)).isFalse(); + } + + @Test + public void notificationInNonHUNGroup_changesAllowed_onReorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + String headsUpGroupKey = "heads_up_group_key"; + mCoordinator.setHeadsUpGroupKeys(Set.of(headsUpGroupKey)); + when(mHeadsUpManager.isHeadsUpEntry(headsUpGroupKey)).thenReturn(true); + + // GIVEN - non HUN parent Group Summary + final NotificationEntry groupSummary = mock(NotificationEntry.class); + when(groupSummary.getKey()).thenReturn("non_heads_up_group_key"); + when(groupSummary.isSummaryWithChildren()).thenReturn(true); + + final GroupEntry nonHeadsUpGroupEntry = mock(GroupEntry.class); + when(nonHeadsUpGroupEntry.getSummary()).thenReturn(groupSummary); + when(nonHeadsUpGroupEntry.getRepresentativeEntry()).thenReturn(groupSummary); + + // GIVEN - child entry in a non heads-up group. + final NotificationEntry childEntry = mock(NotificationEntry.class); + when(childEntry.rowIsChildInGroup()).thenReturn(true); + when(childEntry.getParent()).thenReturn(nonHeadsUpGroupEntry); + when(childEntry.getParent()).thenReturn(nonHeadsUpGroupEntry); + + // THEN + assertThat(mNotifStabilityManager.isGroupChangeAllowed(childEntry)).isTrue(); + assertThat(mNotifStabilityManager.isSectionChangeAllowed(childEntry)).isTrue(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(nonHeadsUpGroupEntry)).isTrue(); + } + + @Test + public void notificationInHUNGroup_changesDisallowed_reorderingEnabled() { + assumeTrue(StabilizeHeadsUpGroup.isEnabled()); + // GIVEN - reordering is allowed. + setPulsing(false); + setPanelExpanded(false); + + // GIVEN - there is a group heads-up. + final String headsUpGroupKey = "heads_up_group_key"; + mCoordinator.setHeadsUpGroupKeys(Set.of(headsUpGroupKey)); + when(mHeadsUpManager.isHeadsUpEntry(headsUpGroupKey)).thenReturn(true); + + // GIVEN - HUN Group Summary + final NotificationEntry headsUpGroupSummary = mock(NotificationEntry.class); + when(headsUpGroupSummary.rowIsChildInGroup()).thenReturn(false); + when(headsUpGroupSummary.getKey()).thenReturn(headsUpGroupKey); + when(headsUpGroupSummary.isSummaryWithChildren()).thenReturn(true); + + final GroupEntry nonHeadsUpGroupEntry = mock(GroupEntry.class); + when(nonHeadsUpGroupEntry.getSummary()).thenReturn(headsUpGroupSummary); + when(nonHeadsUpGroupEntry.getRepresentativeEntry()).thenReturn(headsUpGroupSummary); + + // GIVEN - child entry in a non heads-up group. + final NotificationEntry childEntry = mock(NotificationEntry.class); + when(childEntry.rowIsChildInGroup()).thenReturn(true); + when(childEntry.getParent()).thenReturn(nonHeadsUpGroupEntry); + + // GIVEN - HUN is in visible location + when(mVisibilityLocationProvider.isInVisibleLocation(headsUpGroupSummary)).thenReturn(true); + + // THEN + assertThat(mNotifStabilityManager.isGroupChangeAllowed(childEntry)).isFalse(); + assertThat(mNotifStabilityManager.isSectionChangeAllowed(childEntry)).isFalse(); + assertThat(mNotifStabilityManager.isEntryReorderingAllowed(childEntry)).isFalse(); + } + private void verifyStabilityManagerWasInvalidated(VerificationMode mode) { verify(mInvalidateListener, mode).onPluggableInvalidated(eq(mNotifStabilityManager), any()); } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt index 3d5d1eddf581..9a42f5b02395 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/emptyshade/ui/viewmodel/EmptyShadeViewModelTest.kt @@ -54,7 +54,7 @@ class EmptyShadeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() { private val activeNotificationListRepository = kosmos.activeNotificationListRepository private val fakeSecureSettingsRepository = kosmos.fakeSecureSettingsRepository - private val underTest = kosmos.emptyShadeViewModel + private val underTest by lazy { kosmos.emptyShadeViewModel } companion object { @JvmStatic diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt index 739a9c956178..9dfc922eb7d0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.headsup import android.app.Notification +import android.app.Notification.FLAG_PROMOTED_ONGOING import android.app.PendingIntent import android.app.Person import android.os.Handler @@ -677,10 +678,12 @@ class HeadsUpManagerImplTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test - fun testIsSticky_rowPinnedAndExpanded_true() { - val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) - val row = testHelper.createRow() - row.setPinnedStatus(PinnedStatus.PinnedBySystem) + @DisableFlags(StatusBarNotifChips.FLAG_NAME) + fun testIsSticky_promotedAndExpanded_notifChipsFlagOff_true() { + val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + notif.flags = FLAG_PROMOTED_ONGOING + val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif) + val row = testHelper.createRow().apply { setPinnedStatus(PinnedStatus.PinnedBySystem) } notifEntry.row = row underTest.showNotification(notifEntry) @@ -692,6 +695,23 @@ class HeadsUpManagerImplTest(flags: FlagsParameterization) : SysuiTestCase() { } @Test + @EnableFlags(StatusBarNotifChips.FLAG_NAME) + fun testIsSticky_promotedAndExpanded_notifChipsFlagOn_false() { + val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build() + notif.flags = FLAG_PROMOTED_ONGOING + val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif) + val row = testHelper.createRow().apply { setPinnedStatus(PinnedStatus.PinnedBySystem) } + notifEntry.row = row + + underTest.showNotification(notifEntry) + + val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key) + headsUpEntry!!.setExpanded(true) + + assertThat(underTest.isSticky(notifEntry.key)).isFalse() + } + + @Test fun testIsSticky_remoteInputActive_true() { val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt index d86c6efce284..ba73504b2a03 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.icon.ui.viewmodel import android.graphics.Rect import android.graphics.drawable.Icon +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 com.android.systemui.SysuiTestCase @@ -36,6 +38,7 @@ import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.power.shared.model.WakeSleepReason import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.shade.shadeTestUtil +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository @@ -258,6 +261,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun isolatedIcon_animateOnAppear_shadeCollapsed() = testScope.runTest { val icon: Icon = mock() @@ -285,6 +289,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun isolatedIcon_dontAnimateOnAppear_shadeExpanded() = testScope.runTest { val icon: Icon = mock() @@ -312,6 +317,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun isolatedIcon_updateWhenIconDataChanges() = testScope.runTest { val icon: Icon = mock() @@ -339,6 +345,7 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun isolatedIcon_lastMessageIsFromReply_notNull() = testScope.runTest { val icon: Icon = mock() @@ -362,4 +369,32 @@ class NotificationIconContainerStatusBarViewModelTest(flags: FlagsParameterizati assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1") } + + @Test + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isolatedIcon_noHunBehaviorFlagEnabled_doesNothing() = + testScope.runTest { + val icon: Icon = mock() + val isolatedIcon by collectLastValue(underTest.isolatedIcon) + runCurrent() + + headsUpViewStateRepository.isolatedNotification.value = "notif1" + runCurrent() + + activeNotificationsRepository.activeNotifications.value = + ActiveNotificationsStore.Builder() + .apply { + addIndividualNotif( + activeNotificationModel( + key = "notif1", + groupKey = "group", + statusBarIcon = icon, + ) + ) + } + .build() + runCurrent() + + assertThat(isolatedIcon?.value).isNull() + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java index f7673da6dfb0..4c87e47b8911 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderTest.java @@ -26,12 +26,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; - import androidx.core.os.CancellationSignal; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -51,7 +49,6 @@ import java.util.concurrent.atomic.AtomicReference; @SmallTest public class HeadsUpViewBinderTest extends SysuiTestCase { private HeadsUpViewBinder mViewBinder; - @Mock private NotificationMessagingUtil mNotificationMessagingUtil; @Mock private RowContentBindStage mBindStage; private final HeadsUpViewBinderLogger mLogger = spy( new HeadsUpViewBinderLogger(logcatLogBuffer())); @@ -61,7 +58,7 @@ public class HeadsUpViewBinderTest extends SysuiTestCase { @Before public void setup() { MockitoAnnotations.initMocks(this); - mViewBinder = new HeadsUpViewBinder(mNotificationMessagingUtil, mBindStage, mLogger); + mViewBinder = new HeadsUpViewBinder(mBindStage, mLogger); when(mEntry.getKey()).thenReturn("key"); when(mEntry.getRow()).thenReturn(mRow); when(mBindStage.getStageParams(eq(mEntry))).thenReturn(new RowContentBindParams()); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index a49a66fe26b2..da31cd967a36 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -163,42 +163,6 @@ public class NotificationContentInflaterTest extends SysuiTestCase { } @Test - public void testIncreasedHeadsUpBeingUsed() { - BindParams params = new BindParams(false, false, /* usesIncreasedHeadsUpHeight */ true, - REDACTION_TYPE_NONE); - Notification.Builder builder = spy(mBuilder); - mNotificationInflater.inflateNotificationViews( - mRow.getEntry(), - mRow, - params, - true /* inflateSynchronously */, - FLAG_CONTENT_VIEW_ALL, - builder, - mContext, - mContext, - mSmartReplyStateInflater); - verify(builder).createHeadsUpContentView(true); - } - - @Test - public void testIncreasedHeightBeingUsed() { - BindParams params = new BindParams(false, /* usesIncreasedHeight */ true, false, - REDACTION_TYPE_NONE); - Notification.Builder builder = spy(mBuilder); - mNotificationInflater.inflateNotificationViews( - mRow.getEntry(), - mRow, - params, - true /* inflateSynchronously */, - FLAG_CONTENT_VIEW_ALL, - builder, - mContext, - mContext, - mSmartReplyStateInflater); - verify(builder).createContentView(true); - } - - @Test public void testInflationCallsUpdated() throws Exception { inflateAndWait(mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow); verify(mRow).onNotificationUpdated(); @@ -238,7 +202,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { mRow.getEntry(), mRow, FLAG_CONTENT_VIEW_ALL, - new BindParams(false, false, false, REDACTION_TYPE_NONE), + new BindParams(false, REDACTION_TYPE_NONE), false /* forceInflate */, null /* callback */); Assert.assertNull(mRow.getEntry().getRunningTask()); @@ -576,7 +540,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase { row.getEntry(), row, contentToInflate, - new BindParams(false, false, false, redactionType), + new BindParams(false, redactionType), false /* forceInflate */, callback /* callback */); assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS)); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt index f25ba2c93c65..680b1bee72b2 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt @@ -144,43 +144,6 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() { } @Test - fun testIncreasedHeadsUpBeingUsed() { - val params = - BindParams(false, false, /* usesIncreasedHeadsUpHeight */ true, REDACTION_TYPE_NONE) - val builder = spy(builder) - notificationInflater.inflateNotificationViews( - row.entry, - row, - params, - true, /* inflateSynchronously */ - FLAG_CONTENT_VIEW_ALL, - builder, - mContext, - smartReplyStateInflater, - mock(), - ) - verify(builder).createHeadsUpContentView(true) - } - - @Test - fun testIncreasedHeightBeingUsed() { - val params = BindParams(false, /* usesIncreasedHeight */ true, false, REDACTION_TYPE_NONE) - val builder = spy(builder) - notificationInflater.inflateNotificationViews( - row.entry, - row, - params, - true, /* inflateSynchronously */ - FLAG_CONTENT_VIEW_ALL, - builder, - mContext, - smartReplyStateInflater, - mock(), - ) - verify(builder).createContentView(true) - } - - @Test fun testInflationCallsUpdated() { inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row) verify(row).onNotificationUpdated() @@ -226,7 +189,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() { row.entry, row, FLAG_CONTENT_VIEW_ALL, - BindParams(false, false, false, REDACTION_TYPE_NONE), + BindParams(false, REDACTION_TYPE_NONE), false, /* forceInflate */ null, /* callback */ ) @@ -703,7 +666,7 @@ class NotificationRowContentBinderImplTest : SysuiTestCase() { row.entry, row, contentToInflate, - BindParams(false, false, false, redactionType), + BindParams(false, redactionType), false, /* forceInflate */ callback, /* callback */ ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java index 841cb4a3669b..98e275a473fa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/RowContentBindStageTest.java @@ -214,54 +214,6 @@ public class RowContentBindStageTest extends SysuiTestCase { } @Test - public void testSetUseIncreasedHeight() { - // GIVEN a view with all content bound. - RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); - params.requireContentViews(FLAG_CONTENT_VIEW_ALL); - params.clearDirtyContentViews(); - - // WHEN use increased height is set and stage executed. - params.setUseIncreasedCollapsedHeight(true); - mRowContentBindStage.executeStage(mEntry, mRow, (en) -> { }); - - // THEN binder is called with group view and contracted is bound. - ArgumentCaptor<BindParams> bindParamsCaptor = ArgumentCaptor.forClass(BindParams.class); - verify(mBinder).bindContent( - eq(mEntry), - any(), - eq(FLAG_CONTENT_VIEW_CONTRACTED), - bindParamsCaptor.capture(), - anyBoolean(), - any()); - BindParams usedParams = bindParamsCaptor.getValue(); - assertTrue(usedParams.usesIncreasedHeight); - } - - @Test - public void testSetUseIncreasedHeadsUpHeight() { - // GIVEN a view with all content bound. - RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); - params.requireContentViews(FLAG_CONTENT_VIEW_ALL); - params.clearDirtyContentViews(); - - // WHEN use increased heads up height is set and stage executed. - params.setUseIncreasedHeadsUpHeight(true); - mRowContentBindStage.executeStage(mEntry, mRow, (en) -> { }); - - // THEN binder is called with use group view and heads up is bound. - ArgumentCaptor<BindParams> bindParamsCaptor = ArgumentCaptor.forClass(BindParams.class); - verify(mBinder).bindContent( - eq(mEntry), - any(), - eq(FLAG_CONTENT_VIEW_HEADS_UP), - bindParamsCaptor.capture(), - anyBoolean(), - any()); - BindParams usedParams = bindParamsCaptor.getValue(); - assertTrue(usedParams.usesIncreasedHeadsUpHeight); - } - - @Test public void testSetNeedsReinflation() { // GIVEN a view with all content bound. RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt index 216f51d992d0..bd76268d2cfa 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.kt @@ -34,6 +34,7 @@ import com.android.systemui.shade.shadeViewController import com.android.systemui.statusbar.HeadsUpStatusBarView import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.commandQueue +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor @@ -118,6 +119,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun showingEntryUpdated_whenPinnedBySystem() { row.setPinnedStatus(PinnedStatus.PinnedBySystem) setHeadsUpNotifOnManager(entry) @@ -133,8 +135,18 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test - @DisableFlags(StatusBarNotifChips.FLAG_NAME) - fun showingEntryUpdated_whenPinnedByUser_andFlagOff() { + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun showingEntryNotUpdated_whenPinnedBySystem_whenNoHunBehaviorEnabled() { + row.setPinnedStatus(PinnedStatus.PinnedBySystem) + setHeadsUpNotifOnManager(entry) + underTest.onHeadsUpPinned(entry) + + assertThat(headsUpStatusBarView.showingEntry).isNull() + } + + @Test + @DisableFlags(StatusBarNotifChips.FLAG_NAME, StatusBarNoHunBehavior.FLAG_NAME) + fun showingEntryUpdated_whenPinnedByUser_andNotifChipsFlagOff() { row.setPinnedStatus(PinnedStatus.PinnedByUser) setHeadsUpNotifOnManager(entry) underTest.onHeadsUpPinned(entry) @@ -144,7 +156,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) - fun showingEntryNotUpdated_whenPinnedByUser_andFlagOn() { + fun showingEntryNotUpdated_whenPinnedByUser_andNotifChipsFlagOn() { // WHEN the HUN was pinned by the user row.setPinnedStatus(PinnedStatus.PinnedByUser) setHeadsUpNotifOnManager(entry) @@ -155,6 +167,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun pinnedStatusUpdatedToSystem_whenPinnedBySystem() { row.setPinnedStatus(PinnedStatus.PinnedBySystem) setHeadsUpNotifOnManager(entry) @@ -168,8 +181,19 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun pinnedStatusNotUpdatedToSystem_whenPinnedBySystem_whenNoHunBehaviorEnabled() { + row.setPinnedStatus(PinnedStatus.PinnedBySystem) + setHeadsUpNotifOnManager(entry) + underTest.onHeadsUpPinned(entry) + + assertThat(underTest.pinnedStatus).isEqualTo(PinnedStatus.NotPinned) + } + + @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) - fun pinnedStatusUpdatedToNotPinned_whenPinnedByUser_andFlagOn() { + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun pinnedStatusUpdatedToNotPinned_whenPinnedByUser_andNotifChipsFlagOn() { row.setPinnedStatus(PinnedStatus.PinnedByUser) setHeadsUpNotifOnManager(entry) underTest.onHeadsUpPinned(entry) @@ -182,6 +206,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun isolatedIconSet_whenPinnedBySystem() = kosmos.runTest { val latestIsolatedIcon by @@ -201,8 +226,22 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test - @DisableFlags(StatusBarNotifChips.FLAG_NAME) - fun isolatedIconSet_whenPinnedByUser_andFlagOff() = + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isolatedIconNotSet_whenPinnedBySystem_whenNoHunBehaviorEnabled() = + kosmos.runTest { + val latestIsolatedIcon by + collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification) + + row.setPinnedStatus(PinnedStatus.PinnedBySystem) + setHeadsUpNotifOnManager(entry) + underTest.onHeadsUpPinned(entry) + + assertThat(latestIsolatedIcon).isNull() + } + + @Test + @DisableFlags(StatusBarNotifChips.FLAG_NAME, StatusBarNoHunBehavior.FLAG_NAME) + fun isolatedIconSet_whenPinnedByUser_andNotifChipsFlagOff() = kosmos.runTest { val latestIsolatedIcon by collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification) @@ -216,7 +255,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) - fun isolatedIconNotSet_whenPinnedByUser_andFlagOn() = + fun isolatedIconNotSet_whenPinnedByUser_andNotifChipsFlagOn() = kosmos.runTest { val latestIsolatedIcon by collectLastValue(kosmos.headsUpNotificationIconInteractor.isolatedNotification) @@ -243,6 +282,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) fun operatorNameViewUpdated_whenPinnedBySystem() { underTest.setAnimationsEnabled(false) @@ -258,8 +298,20 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { } @Test - @DisableFlags(StatusBarNotifChips.FLAG_NAME) - fun operatorNameViewUpdated_whenPinnedByUser_andFlagOff() { + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun operatorNameViewNotUpdated_whenPinnedBySystem_whenNoHunBehaviorEnabled() { + underTest.setAnimationsEnabled(false) + + row.setPinnedStatus(PinnedStatus.PinnedBySystem) + setHeadsUpNotifOnManager(entry) + underTest.onHeadsUpPinned(entry) + + assertThat(operatorNameView.visibility).isEqualTo(View.VISIBLE) + } + + @Test + @DisableFlags(StatusBarNotifChips.FLAG_NAME, StatusBarNoHunBehavior.FLAG_NAME) + fun operatorNameViewUpdated_whenPinnedByUser_andNotifChipsFlagOff() { underTest.setAnimationsEnabled(false) row.setPinnedStatus(PinnedStatus.PinnedByUser) @@ -271,7 +323,7 @@ class HeadsUpAppearanceControllerTest : SysuiTestCase() { @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) - fun operatorNameViewNotUpdated_whenPinnedByUser_andFlagOn() { + fun operatorNameViewNotUpdated_whenPinnedByUser_andNotifChipsFlagOn() { underTest.setAnimationsEnabled(false) // WHEN the row was pinned by the user diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java index 650fa7ce46de..58856d970711 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING; + import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertFalse; @@ -44,7 +46,9 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.animation.back.BackAnimationSpec; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.model.SysUiState; +import com.android.systemui.settings.FakeDisplayTracker; import org.junit.Before; import org.junit.Rule; @@ -68,6 +72,7 @@ public class SystemUIDialogTest extends SysuiTestCase { private BroadcastDispatcher mBroadcastDispatcher; @Mock private SystemUIDialog.Delegate mDelegate; + private SysUiState mSysUiState; // TODO(b/292141694): build out Ravenwood support for DeviceFlagsValueProvider // Ravenwood already has solid support for SetFlagsRule, but CheckFlagsRule will be added soon @@ -78,7 +83,9 @@ public class SystemUIDialogTest extends SysuiTestCase { @Before public void setup() { MockitoAnnotations.initMocks(this); - + KosmosJavaAdapter kosmos = new KosmosJavaAdapter(this); + FakeDisplayTracker displayTracker = new FakeDisplayTracker(mContext); + mSysUiState = new SysUiState(displayTracker, kosmos.getSceneContainerPlugin()); mDependency.injectTestDependency(BroadcastDispatcher.class, mBroadcastDispatcher); when(mDelegate.getBackAnimationSpec(ArgumentMatchers.any())) .thenReturn(mock(BackAnimationSpec.class)); @@ -173,6 +180,30 @@ public class SystemUIDialogTest extends SysuiTestCase { assertThat(calledStop.get()).isTrue(); } + /** Regression test for b/386871258 */ + @Test + public void sysuiStateUpdated() { + SystemUIDialog dialog1 = + createDialogWithDelegate(mContext, mDelegate, /* shouldAcsDismissDialog */ true); + SystemUIDialog dialog2 = + createDialogWithDelegate(mContext, mDelegate, /* shouldAcsDismissDialog */ true); + + dialog1.show(); + assertThat((mSysUiState.getFlags() & SYSUI_STATE_DIALOG_SHOWING) != 0).isTrue(); + + dialog2.show(); + assertThat((mSysUiState.getFlags() & SYSUI_STATE_DIALOG_SHOWING) != 0).isTrue(); + + dialog2.dismiss(); + // explicitly call onWindowFocusChanged to simulate dialog 1 regaining focus + dialog1.onWindowFocusChanged(/* hasFocus= */ true); + assertThat((mSysUiState.getFlags() & SYSUI_STATE_DIALOG_SHOWING) != 0).isTrue(); + + dialog1.dismiss(); + assertThat((mSysUiState.getFlags() & SYSUI_STATE_DIALOG_SHOWING) != 0).isFalse(); + } + + @Test public void delegateIsCalled_inCorrectOrder() { Configuration configuration = new Configuration(); @@ -198,7 +229,7 @@ public class SystemUIDialogTest extends SysuiTestCase { SystemUIDialog.Factory factory = new SystemUIDialog.Factory( getContext(), Dependency.get(SystemUIDialogManager.class), - Dependency.get(SysUiState.class), + mSysUiState, Dependency.get(BroadcastDispatcher.class), Dependency.get(DialogTransitionAnimator.class) ); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index 6da06a36f63d..02135f6a7836 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.notification.data.model.activeNotification import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository @@ -169,6 +170,27 @@ class OngoingCallControllerTest : SysuiTestCase() { } @Test + fun interactorHasOngoingCallNotif_repoHasPromotedContent() = + testScope.runTest { + val promotedContent = PromotedNotificationContentModel.Builder("ongoingNotif").build() + setNotifOnRepo( + activeNotificationModel( + key = "ongoingNotif", + callType = CallType.Ongoing, + uid = CALL_UID, + statusBarChipIcon = mock(), + whenTime = 567, + promotedContent = promotedContent, + ) + ) + + val repoState = ongoingCallRepository.ongoingCallState.value + assertThat(repoState).isInstanceOf(OngoingCallModel.InCall::class.java) + assertThat((repoState as OngoingCallModel.InCall).promotedContent) + .isEqualTo(promotedContent) + } + + @Test fun notifRepoHasOngoingCallNotif_isOngoingCallNotif_windowControllerUpdated() { setCallNotifOnRepo() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt index 8fb95e843ec1..14263c4b1b9b 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt @@ -35,6 +35,7 @@ import com.android.systemui.statusbar.gesture.swipeStatusBarAwayGestureHandler import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore @@ -69,33 +70,37 @@ class OngoingCallInteractorTest : SysuiTestCase() { } @Test - fun ongoingCallNotification_setsNotificationIconAndIntent() = + fun ongoingCallNotification_setsAllFields() = kosmos.runTest { val latest by collectLastValue(underTest.ongoingCallState) // Set up notification with icon view and intent val testIconView: StatusBarIconView = mock() val testIntent: PendingIntent = mock() + val testPromotedContent = + PromotedNotificationContentModel.Builder("promotedCall").build() repository.activeNotifications.value = ActiveNotificationsStore.Builder() .apply { addIndividualNotif( activeNotificationModel( - key = "notif1", + key = "promotedCall", whenTime = 1000L, callType = CallType.Ongoing, statusBarChipIcon = testIconView, contentIntent = testIntent, + promotedContent = testPromotedContent, ) ) } .build() - // Verify model is InCall and has the correct icon and intent. + // Verify model is InCall and has the correct icon, intent, and promoted content. assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java) val model = latest as OngoingCallModel.InCall assertThat(model.notificationIconView).isSameInstanceAs(testIconView) assertThat(model.intent).isSameInstanceAs(testIntent) + assertThat(model.promotedContent).isSameInstanceAs(testPromotedContent) } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt index 937f333b0065..a1c910d48cef 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt @@ -24,6 +24,8 @@ import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChip import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel +import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel +import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -51,28 +53,15 @@ class FakeHomeStatusBarViewModel( override val shouldShowOperatorNameView = MutableStateFlow(false) override val isClockVisible = - MutableStateFlow( - HomeStatusBarViewModel.VisibilityModel( - visibility = View.GONE, - shouldAnimateChange = false, - ) - ) + MutableStateFlow(VisibilityModel(visibility = View.GONE, shouldAnimateChange = false)) override val isNotificationIconContainerVisible = - MutableStateFlow( - HomeStatusBarViewModel.VisibilityModel( - visibility = View.GONE, - shouldAnimateChange = false, - ) - ) + MutableStateFlow(VisibilityModel(visibility = View.GONE, shouldAnimateChange = false)) override val systemInfoCombinedVis = MutableStateFlow( - HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( - HomeStatusBarViewModel.VisibilityModel( - visibility = View.GONE, - shouldAnimateChange = false, - ), + SystemInfoCombinedVisibilityModel( + VisibilityModel(visibility = View.GONE, shouldAnimateChange = false), Idle, ) ) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt index be4af868b740..e74d009bb909 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt @@ -70,6 +70,7 @@ import com.android.systemui.statusbar.events.data.repository.systemStatusEventAn import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingIn import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.AnimatingOut import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.data.model.activeNotificationModel import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore import com.android.systemui.statusbar.notification.data.repository.UnconfinedFakeHeadsUpRowRepository @@ -82,12 +83,11 @@ import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarIconBlockList import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarInteractorShowOperatorName -import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel +import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel 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.emptyFlow import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.UnconfinedTestDispatcher import org.junit.Before @@ -422,8 +422,9 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { fun areNotificationsLightsOut_requiresFlagEnabled() = kosmos.runTest { assertLogsWtf { - val flow = underTest.areNotificationsLightsOut - assertThat(flow).isEqualTo(emptyFlow<Boolean>()) + val latest by collectLastValue(underTest.areNotificationsLightsOut) + // Nothing is emitted + assertThat(latest).isNull() } } @@ -552,9 +553,10 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test - fun shouldShowOperatorNameView_allowedByInteractor_hunPinned_false() = + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun shouldShowOperatorNameView_allowedByInteractor_hunPinned_noHunBehaviorFlagOff_false() = kosmos.runTest { - kosmos.setHomeStatusBarInteractorShowOperatorName(false) + kosmos.setHomeStatusBarInteractorShowOperatorName(true) transitionKeyguardToGone() @@ -565,7 +567,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { headsUpNotificationRepository.setNotifications( UnconfinedFakeHeadsUpRowRepository( key = "key", - pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser), + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem), ) ) @@ -575,6 +577,31 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun shouldShowOperatorNameView_allowedByInteractor_hunPinned_noHunBehaviorFlagOn_true() = + kosmos.runTest { + kosmos.setHomeStatusBarInteractorShowOperatorName(true) + + transitionKeyguardToGone() + + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + + // WHEN there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem), + ) + ) + + val latest by collectLastValue(underTest.shouldShowOperatorNameView) + + // THEN we still show the operator name view if NoHunBehavior flag is enabled + assertThat(latest).isTrue() + } + + @Test fun shouldHomeStatusBarBeVisible_keyguardNotGone_noHun_false() = kosmos.runTest { // Do not transition from keyguard. i.e., we don't call transitionKeyguardToGone() @@ -692,7 +719,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { @Test @EnableFlags(StatusBarNotifChips.FLAG_NAME) - fun isClockVisible_allowedByFlags_hunPinnedByUser_visible() = + fun isClockVisible_allowedByDisableFlags_hunPinnedByUser_visible() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) transitionKeyguardToGone() @@ -711,7 +738,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test - fun isClockVisible_allowedByFlags_hunPinnedBySystem_notVisible() = + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isClockVisible_allowedByDisableFlags_hunPinnedBySystem_noHunBehaviorFlagOff_notVisible() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) transitionKeyguardToGone() @@ -730,7 +758,29 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test - fun isClockVisible_allowedByFlags_hunBecomesInactive_visibleAgain() = + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isClockVisible_allowedByDisableFlags_hunPinnedBySystem_noHunBehaviorFlagOn_visible() = + kosmos.runTest { + val latest by collectLastValue(underTest.isClockVisible) + transitionKeyguardToGone() + + fakeDisableFlagsRepository.disableFlags.value = + DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE) + // WHEN there is an active HUN + headsUpNotificationRepository.setNotifications( + UnconfinedFakeHeadsUpRowRepository( + key = "key", + pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem), + ) + ) + + // THEN we still show the clock view if NoHunBehavior flag is enabled + assertThat(latest!!.visibility).isEqualTo(View.VISIBLE) + } + + @Test + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isClockVisible_allowedByDisableFlags_hunBecomesInactive_visibleAgain() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) transitionKeyguardToGone() @@ -753,7 +803,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() { } @Test - fun isClockVisible_disabledByFlags_hunBecomesInactive_neverVisible() = + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isClockVisible_disableFlagsProhibitClock_hunBecomesInactive_neverVisible() = kosmos.runTest { val latest by collectLastValue(underTest.isClockVisible) transitionKeyguardToGone() diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt index 7c47264d448a..ff1ffccfb2de 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt @@ -57,7 +57,7 @@ class ZenModeInteractorTest : SysuiTestCase() { private val settingsRepository = kosmos.secureSettingsRepository private val deviceProvisioningRepository = kosmos.fakeDeviceProvisioningRepository - private val underTest = kosmos.zenModeInteractor + private val underTest by lazy { kosmos.zenModeInteractor } @Test fun isZenAvailable_off() = @@ -176,13 +176,13 @@ class ZenModeInteractorTest : SysuiTestCase() { @Test fun shouldAskForZenDuration_changesWithSetting() = kosmos.runTest { - val manualDnd = TestModeBuilder().makeManualDnd().setActive(true).build() + val manualDnd by collectLastValue(underTest.dndMode) settingsRepository.setInt(ZEN_DURATION, ZEN_DURATION_FOREVER) - assertThat(underTest.shouldAskForZenDuration(manualDnd)).isFalse() + assertThat(underTest.shouldAskForZenDuration(manualDnd!!)).isFalse() settingsRepository.setInt(ZEN_DURATION, ZEN_DURATION_PROMPT) - assertThat(underTest.shouldAskForZenDuration(manualDnd)).isTrue() + assertThat(underTest.shouldAskForZenDuration(manualDnd!!)).isTrue() } @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt index b2378d2c3aae..2d6315014164 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateTest.kt @@ -66,13 +66,14 @@ class ModesDialogDelegateTest : SysuiTestCase() { whenever( mockDialogTransitionAnimator.createActivityTransitionController( any<SystemUIDialog>(), - eq(null) + eq(null), ) ) .thenReturn(mockAnimationController) underTest = ModesDialogDelegate( + context, kosmos.systemUIDialogFactory, mockDialogTransitionAnimator, activityStarter, diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt index 0598b87aec9d..73e5004d47f0 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.ui.viewmodel +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 com.android.systemui.SysuiTestCase @@ -32,6 +34,7 @@ import com.android.systemui.scene.data.repository.sceneContainerRepository import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor @@ -127,7 +130,8 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa @Test @EnableSceneContainer - fun isVisible_headsUpStatusBarShown_false() = + @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isVisible_headsUpShown_noHunBehaviorFlagOff_false() = testScope.runTest { val latest by collectLastValue(underTest.isVisible) @@ -145,6 +149,26 @@ class KeyguardStatusBarViewModelTest(flags: FlagsParameterization) : SysuiTestCa } @Test + @EnableSceneContainer + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + fun isVisible_headsUpShown_noHunBehaviorFlagOn_true() = + testScope.runTest { + val latest by collectLastValue(underTest.isVisible) + + // WHEN HUN displayed on the bypass lock screen + headsUpRepository.setNotifications(FakeHeadsUpRowRepository("key 0", isPinned = true)) + keyguardTransitionRepository.emitInitialStepsFromOff( + KeyguardState.LOCKSCREEN, + testSetup = true, + ) + kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen) + faceAuthRepository.isBypassEnabled.value = true + + // THEN KeyguardStatusBar is still visible because StatusBarNoHunBehavior is enabled + assertThat(latest).isTrue() + } + + @Test fun isVisible_sceneLockscreen_andNotDozing_andNotShowingHeadsUpStatusBar_true() = testScope.runTest { val latest by collectLastValue(underTest.isVisible) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt index d8184dbadf9a..2dcfdd958df1 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelTest.kt @@ -30,6 +30,7 @@ import com.android.systemui.haptics.fakeVibratorHelper import com.android.systemui.kosmos.testScope import com.android.systemui.plugins.fakeVolumeDialogController import com.android.systemui.testKosmos +import com.android.systemui.util.time.fakeSystemClock import com.android.systemui.volume.data.repository.audioSystemRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -78,7 +79,7 @@ class VolumeDialogRingerDrawerViewModelTest : SysuiTestCase() { val normalRingerMode = RingerMode(RINGER_MODE_NORMAL) setUpRingerModeAndOpenDrawer(normalRingerMode) - underTest.onRingerButtonClicked(normalRingerMode) + onRingerButtonClicked(normalRingerMode) controller.getState() assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Available::class.java) @@ -95,7 +96,7 @@ class VolumeDialogRingerDrawerViewModelTest : SysuiTestCase() { setUpRingerModeAndOpenDrawer(normalRingerMode) // Select vibrate ringer mode. - underTest.onRingerButtonClicked(vibrateRingerMode) + onRingerButtonClicked(vibrateRingerMode) controller.getState() runCurrent() @@ -109,11 +110,11 @@ class VolumeDialogRingerDrawerViewModelTest : SysuiTestCase() { val silentRingerMode = RingerMode(RINGER_MODE_SILENT) // Open drawer - underTest.onRingerButtonClicked(vibrateRingerMode) + onRingerButtonClicked(vibrateRingerMode) controller.getState() // Select silent ringer mode. - underTest.onRingerButtonClicked(silentRingerMode) + onRingerButtonClicked(silentRingerMode) controller.getState() runCurrent() @@ -152,11 +153,16 @@ class VolumeDialogRingerDrawerViewModelTest : SysuiTestCase() { private fun TestScope.setUpRingerModeAndOpenDrawer(selectedRingerMode: RingerMode) { setUpRingerMode(selectedRingerMode) - underTest.onRingerButtonClicked(RingerMode(selectedRingerMode.value)) + onRingerButtonClicked(selectedRingerMode) controller.getState() runCurrent() } + private fun TestScope.onRingerButtonClicked(ringerMode: RingerMode) { + kosmos.fakeSystemClock.advanceTime(400L) + underTest.onRingerButtonClicked(ringerMode) + } + private fun TestScope.setUpRingerMode(selectedRingerMode: RingerMode) { controller.setStreamVolume(STREAM_RING, 50) controller.setRingerMode(selectedRingerMode.value, false) diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt index c9d147b6c81c..09d6ac6589ed 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractorTest.kt @@ -16,11 +16,16 @@ package com.android.systemui.volume.domain.interactor +import android.bluetooth.BluetoothDevice import android.media.AudioManager.STREAM_MUSIC import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.SysuiTestCase +import com.android.systemui.bluetooth.cachedBluetoothDeviceManager +import com.android.systemui.bluetooth.localBluetoothProfileManager import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos @@ -32,6 +37,8 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) @@ -39,10 +46,23 @@ import org.junit.runner.RunWith class AudioSharingInteractorTest : SysuiTestCase() { private val kosmos = testKosmos() lateinit var underTest: AudioSharingInteractor + private val bluetoothDevice: BluetoothDevice = mock {} + private val cachedDevice: CachedBluetoothDevice = mock { + on { groupId }.thenReturn(TEST_GROUP_ID) + on { device }.thenReturn(bluetoothDevice) + } @Before fun setUp() { with(kosmos) { + whenever(cachedBluetoothDeviceManager.findDevice(bluetoothDevice)) + .thenReturn(cachedDevice) + val broadcastAssistantProfile: LocalBluetoothLeBroadcastAssistant = mock { + on { allConnectedDevices }.thenReturn(listOf(bluetoothDevice)) + } + whenever(localBluetoothProfileManager.leAudioBroadcastAssistantProfile) + .thenReturn(broadcastAssistantProfile) + with(audioSharingRepository) { setVolumeMap(mapOf(TEST_GROUP_ID to TEST_VOLUME)) } underTest = audioSharingInteractor } @@ -90,6 +110,35 @@ class AudioSharingInteractorTest : SysuiTestCase() { } @Test + fun getPrimaryDevice() { + with(kosmos) { + testScope.runTest { + with(audioSharingRepository) { setPrimaryDevice(cachedDevice) } + underTest.handlePrimaryGroupChange() + + val primaryDevice by collectLastValue(underTest.primaryDevice) + runCurrent() + + Truth.assertThat(primaryDevice).isEqualTo(cachedDevice) + } + } + } + + @Test + fun getSecondaryDevice() { + with(kosmos) { + testScope.runTest { + with(audioSharingRepository) { setSecondaryDevice(cachedDevice) } + + val secondaryDevice by collectLastValue(underTest.secondaryDevice) + runCurrent() + + Truth.assertThat(secondaryDevice).isEqualTo(cachedDevice) + } + } + } + + @Test fun handlePrimaryGroupChange_setStreamVolume() { with(kosmos) { testScope.runTest { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt new file mode 100644 index 000000000000..b34d7b8ec17d --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt @@ -0,0 +1,91 @@ +/* + * 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.bluetooth.BluetoothDevice +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.internal.logging.uiEventLogger +import com.android.settingslib.bluetooth.CachedBluetoothDevice +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory +import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R +import com.android.systemui.testKosmos +import com.android.systemui.volume.data.repository.audioSharingRepository +import com.android.systemui.volume.domain.interactor.audioSharingInteractor +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class AudioSharingStreamSliderViewModelTest : SysuiTestCase() { + + private val kosmos = testKosmos() + private val testScope = kosmos.testScope + + private lateinit var stream: AudioSharingStreamSliderViewModel + + @Before + fun setUp() { + stream = audioSharingStreamSliderViewModel() + } + + private fun audioSharingStreamSliderViewModel(): AudioSharingStreamSliderViewModel { + return AudioSharingStreamSliderViewModel( + testScope.backgroundScope, + context, + kosmos.audioSharingInteractor, + kosmos.uiEventLogger, + kosmos.sliderHapticsViewModelFactory, + ) + } + + @Test + fun slider_media_inAudioSharing() = + with(kosmos) { + testScope.runTest { + val audioSharingSlider by collectLastValue(stream.slider) + + val bluetoothDevice: BluetoothDevice = mock {} + val cachedDevice: CachedBluetoothDevice = mock { + on { groupId }.thenReturn(123) + on { device }.thenReturn(bluetoothDevice) + on { name }.thenReturn("my headset 2") + } + audioSharingRepository.setSecondaryDevice(cachedDevice) + + audioSharingRepository.setInAudioSharing(true) + audioSharingRepository.setSecondaryGroupId(123) + + runCurrent() + + assertThat(audioSharingSlider!!.label).isEqualTo("my headset 2") + assertThat(audioSharingSlider!!.icon) + .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null)) + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt index 51cac6976362..9e8cde3bc936 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt @@ -23,19 +23,27 @@ import android.platform.test.annotations.EnableFlags import android.service.notification.ZenPolicy import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.notification.modes.TestModeBuilder import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.SysuiTestCase +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.runTest +import com.android.systemui.res.R import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository import com.android.systemui.testKosmos +import com.android.systemui.volume.data.repository.audioSharingRepository import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.mock @SmallTest @RunWith(AndroidJUnit4::class) @@ -146,4 +154,25 @@ class AudioStreamSliderViewModelTest : SysuiTestCase() { assertThat(notificationSlider!!.disabledMessage) .isEqualTo("Unavailable because ring is muted") } + + @Test + @EnableFlags(com.android.systemui.Flags.FLAG_SHOW_AUDIO_SHARING_SLIDER_IN_VOLUME_PANEL) + fun slider_media_inAudioSharing() = + kosmos.runTest { + val mediaSlider by + collectLastValue(audioStreamSliderViewModel(AudioManager.STREAM_MUSIC).slider) + + val cachedDevice: CachedBluetoothDevice = mock { + on { groupId }.thenReturn(123) + on { name }.thenReturn("my headset 1") + } + + audioSharingRepository.setInAudioSharing(true) + audioSharingRepository.setPrimaryDevice(cachedDevice) + runCurrent() + + assertThat(mediaSlider!!.label).isEqualTo("my headset 1") + assertThat(mediaSlider!!.icon) + .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null)) + } } diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags index 02b2bcf8e40d..e152c98a93e5 100644 --- a/packages/SystemUI/proguard_common.flags +++ b/packages/SystemUI/proguard_common.flags @@ -58,3 +58,8 @@ static *** v(...); } -maximumremovedandroidloglevel 2 + +#Keep the R +-keepclassmembers class com.android.systemui.customization.R$* { + public static <fields>; +} diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml index 0b289b7a44c0..8d78e6bd7cd0 100644 --- a/packages/SystemUI/res-product/values-iw/strings.xml +++ b/packages/SystemUI/res-product/values-iw/strings.xml @@ -21,7 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="dock_alignment_slow_charging" product="default" msgid="6997633396534416792">"צריך ליישר את הטלפון כדי לטעון אותו במהירות"</string> <string name="dock_alignment_not_charging" product="default" msgid="3980752926226749808">"צריך ליישר את הטלפון כדי לטעון אותו באופן אלחוטי"</string> - <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"מכשיר ה-Android TV ייכבה בקרוב. יש ללחוץ על לחצן כלשהו כדי שהוא ימשיך לפעול."</string> + <string name="inattentive_sleep_warning_message" product="tv" msgid="6844464574089665063">"מכשיר ה-Android TV ייכבה בקרוב. יש ללחוץ על כפתור כלשהו כדי שהוא ימשיך לפעול."</string> <string name="inattentive_sleep_warning_message" product="default" msgid="5693904520452332224">"המכשיר ייכבה בקרוב, יש ללחוץ כדי שהוא ימשיך לפעול."</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="408124574073032188">"אין כרטיס SIM בטאבלט."</string> <string name="keyguard_missing_sim_message" product="default" msgid="2605468359948247208">"אין כרטיס SIM בטלפון."</string> @@ -43,24 +43,24 @@ <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"הטלפון כבה בגלל התחממות"</string> <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"המכשיר כבה בגלל התחממות"</string> <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"הטאבלט כבה בגלל התחממות"</string> - <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"הטלפון פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string> - <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"המכשיר פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string> - <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"הטאבלט פועל כרגיל עכשיו.\nיש להקיש כדי להציג מידע נוסף"</string> + <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"הטלפון פועל כרגיל עכשיו.\nיש ללחוץ כדי להציג מידע נוסף"</string> + <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"המכשיר פועל כרגיל עכשיו.\nיש ללחוץ כדי להציג מידע נוסף"</string> + <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"הטאבלט פועל כרגיל עכשיו.\nיש ללחוץ כדי להציג מידע נוסף"</string> <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"הטלפון שלך התחמם יותר מדי וכבה כדי להתקרר. הטלפון פועל כרגיל עכשיו.\n\nייתכן שהטלפון יתחמם יותר מדי אם:\n • משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n • מורידים או מעלים קבצים גדולים.\n • משתמשים בטלפון בסביבה עם טמפרטורות גבוהות."</string> <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"המכשיר שלך התחמם יותר מדי וכבה כדי להתקרר. המכשיר פועל כרגיל עכשיו.\n\nייתכן שהמכשיר יתחמם יותר מדי אם:\n • משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n • מורידים או מעלים קבצים גדולים.\n • משתמשים במכשיר בסביבה עם טמפרטורות גבוהות."</string> <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"הטאבלט שלך התחמם יותר מדי וכבה כדי להתקרר. הטאבלט פועל כרגיל עכשיו.\n\nייתכן שהטאבלט יתחמם יותר מדי אם:\n • משתמשים באפליקציות עתירות משאבים (כמו משחקים, אפליקציות וידאו או אפליקציות ניווט).\n • מורידים או מעלים קבצים גדולים.\n • משתמשים בטאבלט בסביבה עם טמפרטורות גבוהות."</string> <string name="high_temp_title" product="default" msgid="5365000411304924115">"הטלפון מתחמם"</string> <string name="high_temp_title" product="device" msgid="6622009907401563664">"המכשיר מתחמם"</string> <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"הטאבלט מתחמם"</string> - <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string> - <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"חלק מהתכונות מוגבלות כל עוד המכשיר מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string> - <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"חלק מהתכונות מוגבלות כל עוד הטאבלט מתקרר.\nיש להקיש כדי להציג מידע נוסף"</string> + <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"חלק מהתכונות מוגבלות כל עוד הטלפון מתקרר.\nיש ללחוץ כדי להציג מידע נוסף"</string> + <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"חלק מהתכונות מוגבלות כל עוד המכשיר מתקרר.\nיש ללחוץ כדי להציג מידע נוסף"</string> + <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"חלק מהתכונות מוגבלות כל עוד הטאבלט מתקרר.\nיש ללחוץ כדי להציג מידע נוסף"</string> <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"קירור הטלפון ייעשה באופן אוטומטי. אפשר עדיין להשתמש בטלפון, אבל ייתכן שהוא יפעל לאט יותר.\n\nהטלפון יחזור לפעול כרגיל לאחר שיתקרר."</string> <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"קירור המכשיר ייעשה באופן אוטומטי. אפשר עדיין להשתמש במכשיר אבל ייתכן שהוא יפעל לאט יותר.\n\nהמכשיר יחזור לפעול כרגיל לאחר שיתקרר."</string> <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"קירור הטאבלט ייעשה באופן אוטומטי. אפשר עדיין להשתמש בטאבלט אבל ייתכן שהוא יפעל לאט יותר.\n\nהטאבלט יחזור לפעול כרגיל לאחר שיתקרר."</string> - <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בקצה הטאבלט."</string> - <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי המכשיר."</string> - <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בקצה הטלפון."</string> + <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"חיישן טביעות האצבע נמצא על כפתור ההפעלה. זה הכפתור השטוח ליד הכפתור הבולט של עוצמת הקול בקצה הטאבלט."</string> + <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"חיישן טביעות האצבע נמצא על כפתור ההפעלה. זה הכפתור השטוח ליד הכפתור הבולט של עוצמת הקול בשולי המכשיר."</string> + <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"חיישן טביעות האצבע נמצא על כפתור ההפעלה. זה הכפתור השטוח ליד הכפתור הבולט של עוצמת הקול בקצה הטלפון."</string> <string name="global_action_lock_message" product="default" msgid="7092460751050168771">"לאפשרויות נוספות, יש לבטל את נעילת הטלפון"</string> <string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"לאפשרויות נוספות, יש לבטל את נעילת הטאבלט"</string> <string name="global_action_lock_message" product="device" msgid="3165224897120346096">"לאפשרויות נוספות, יש לבטל את נעילת המכשיר"</string> diff --git a/packages/SystemUI/res/drawable/ic_media_connecting_button_container.xml b/packages/SystemUI/res/drawable/ic_media_connecting_button_container.xml new file mode 100644 index 000000000000..32aacf6522e7 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_media_connecting_button_container.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="88dp" + android:height="56dp" + android:viewportHeight="56" + android:viewportWidth="88"> + <group android:name="_R_G"> + <group + android:name="_R_G_L_1_G" + android:scaleX="1.05905" + android:scaleY="1.0972" + android:translateX="43.528999999999996" + android:translateY="27.898" /> + <group + android:name="_R_G_L_0_G" + android:pivotX="0.493" + android:pivotY="0.124" + android:scaleX="1.05905" + android:scaleY="1.0972" + android:translateX="43.528999999999996" + android:translateY="27.898"> + <path + android:name="_R_G_L_0_G_D_0_P_0" + android:fillAlpha="1" + android:fillColor="#3d90ff" + android:fillType="nonZero" + android:pathData=" M34.49 -5.75 C34.49,-5.75 34.49,6 34.49,6 C34.49,14.84 27.32,22 18.49,22 C18.49,22 -17.5,22 -17.5,22 C-26.34,22 -33.5,14.84 -33.5,6 C-33.5,6 -33.5,-5.75 -33.5,-5.75 C-33.5,-14.59 -26.34,-21.75 -17.5,-21.75 C-17.5,-21.75 18.49,-21.75 18.49,-21.75 C27.32,-21.75 34.49,-14.59 34.49,-5.75c " /> + </group> + </group> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_media_connecting_status_container.xml b/packages/SystemUI/res/drawable/ic_media_connecting_status_container.xml deleted file mode 100644 index f8c0fa04cd39..000000000000 --- a/packages/SystemUI/res/drawable/ic_media_connecting_status_container.xml +++ /dev/null @@ -1,199 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?><!-- - ~ Copyright (C) 2025 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. - --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:aapt="http://schemas.android.com/aapt"> - <target android:name="_R_G_L_1_G"> - <aapt:attr name="android:animation"> - <set android:ordering="together"> - <objectAnimator - android:duration="83" - android:propertyName="scaleX" - android:startOffset="1000" - android:valueFrom="0.45561" - android:valueTo="0.69699" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,0.15 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="83" - android:propertyName="scaleY" - android:startOffset="1000" - android:valueFrom="0.6288400000000001" - android:valueTo="0.81618" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,0.15 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="417" - android:propertyName="scaleX" - android:startOffset="1083" - android:valueFrom="0.69699" - android:valueTo="1.05905" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.05,0.7 0.1,1 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="417" - android:propertyName="scaleY" - android:startOffset="1083" - android:valueFrom="0.81618" - android:valueTo="1.0972" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.05,0.7 0.1,1 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - </set> - </aapt:attr> - </target> - <target android:name="_R_G_L_0_G"> - <aapt:attr name="android:animation"> - <set android:ordering="together"> - <objectAnimator - android:duration="500" - android:propertyName="rotation" - android:startOffset="0" - android:valueFrom="90" - android:valueTo="135" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="500" - android:propertyName="rotation" - android:startOffset="500" - android:valueFrom="135" - android:valueTo="180" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - </set> - </aapt:attr> - </target> - <target android:name="_R_G_L_0_G"> - <aapt:attr name="android:animation"> - <set android:ordering="together"> - <objectAnimator - android:duration="83" - android:propertyName="scaleX" - android:startOffset="1000" - android:valueFrom="0.0434" - android:valueTo="0.05063" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,0.15 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="83" - android:propertyName="scaleY" - android:startOffset="1000" - android:valueFrom="0.0434" - android:valueTo="0.042350000000000006" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.3,0 0.8,0.15 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="417" - android:propertyName="scaleX" - android:startOffset="1083" - android:valueFrom="0.05063" - android:valueTo="0.06146" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.05,0.7 0.1,1 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - <objectAnimator - android:duration="417" - android:propertyName="scaleY" - android:startOffset="1083" - android:valueFrom="0.042350000000000006" - android:valueTo="0.040780000000000004" - android:valueType="floatType"> - <aapt:attr name="android:interpolator"> - <pathInterpolator android:pathData="M 0.0,0.0 c0.05,0.7 0.1,1 1.0,1.0" /> - </aapt:attr> - </objectAnimator> - </set> - </aapt:attr> - </target> - <target android:name="time_group"> - <aapt:attr name="android:animation"> - <set android:ordering="together"> - <objectAnimator - android:duration="1017" - android:propertyName="translateX" - android:startOffset="0" - android:valueFrom="0" - android:valueTo="1" - android:valueType="floatType" /> - </set> - </aapt:attr> - </target> - <aapt:attr name="android:drawable"> - <vector - android:width="88dp" - android:height="56dp" - android:viewportHeight="56" - android:viewportWidth="88"> - <group android:name="_R_G"> - <group - android:name="_R_G_L_1_G" - android:pivotX="0.493" - android:pivotY="0.124" - android:scaleX="1.05905" - android:scaleY="1.0972" - android:translateX="43.528999999999996" - android:translateY="27.898"> - <path - android:name="_R_G_L_1_G_D_0_P_0" - android:fillAlpha="1" - android:fillColor="#3d90ff" - android:fillType="nonZero" - android:pathData=" M34.47 0.63 C34.47,0.63 34.42,0.64 34.42,0.64 C33.93,12.88 24.69,21.84 13.06,21.97 C13.06,21.97 -12.54,21.97 -12.54,21.97 C-23.11,21.84 -33.38,13.11 -33.52,-0.27 C-33.52,-0.27 -33.52,-0.05 -33.52,-0.05 C-33.5,-13.21 -21.73,-21.76 -12.9,-21.76 C-12.9,-21.76 14.59,-21.76 14.59,-21.76 C24.81,-21.88 34.49,-10.58 34.47,0.63c " /> - </group> - <group - android:name="_R_G_L_0_G" - android:rotation="0" - android:scaleX="0.06146" - android:scaleY="0.040780000000000004" - android:translateX="44" - android:translateY="28"> - <path - android:name="_R_G_L_0_G_D_0_P_0" - android:fillAlpha="1" - android:fillColor="#3d90ff" - android:fillType="nonZero" - android:pathData=" M-0.65 -437.37 C-0.65,-437.37 8.33,-437.66 8.33,-437.66 C8.33,-437.66 17.31,-437.95 17.31,-437.95 C17.31,-437.95 26.25,-438.78 26.25,-438.78 C26.25,-438.78 35.16,-439.95 35.16,-439.95 C35.16,-439.95 44.07,-441.11 44.07,-441.11 C44.07,-441.11 52.85,-443 52.85,-443 C52.85,-443 61.6,-445.03 61.6,-445.03 C61.6,-445.03 70.35,-447.09 70.35,-447.09 C70.35,-447.09 78.91,-449.83 78.91,-449.83 C78.91,-449.83 87.43,-452.67 87.43,-452.67 C87.43,-452.67 95.79,-455.97 95.79,-455.97 C95.79,-455.97 104.11,-459.35 104.11,-459.35 C104.11,-459.35 112.36,-462.93 112.36,-462.93 C112.36,-462.93 120.6,-466.51 120.6,-466.51 C120.6,-466.51 128.84,-470.09 128.84,-470.09 C128.84,-470.09 137.09,-473.67 137.09,-473.67 C137.09,-473.67 145.49,-476.84 145.49,-476.84 C145.49,-476.84 153.9,-480.01 153.9,-480.01 C153.9,-480.01 162.31,-483.18 162.31,-483.18 C162.31,-483.18 170.98,-485.54 170.98,-485.54 C170.98,-485.54 179.66,-487.85 179.66,-487.85 C179.66,-487.85 188.35,-490.15 188.35,-490.15 C188.35,-490.15 197.22,-491.58 197.22,-491.58 C197.22,-491.58 206.09,-493.01 206.09,-493.01 C206.09,-493.01 214.98,-494.28 214.98,-494.28 C214.98,-494.28 223.95,-494.81 223.95,-494.81 C223.95,-494.81 232.93,-495.33 232.93,-495.33 C232.93,-495.33 241.9,-495.5 241.9,-495.5 C241.9,-495.5 250.88,-495.13 250.88,-495.13 C250.88,-495.13 259.86,-494.75 259.86,-494.75 C259.86,-494.75 268.78,-493.78 268.78,-493.78 C268.78,-493.78 277.68,-492.52 277.68,-492.52 C277.68,-492.52 286.57,-491.26 286.57,-491.26 C286.57,-491.26 295.31,-489.16 295.31,-489.16 C295.31,-489.16 304.04,-487.04 304.04,-487.04 C304.04,-487.04 312.7,-484.65 312.7,-484.65 C312.7,-484.65 321.19,-481.72 321.19,-481.72 C321.19,-481.72 329.68,-478.78 329.68,-478.78 C329.68,-478.78 337.96,-475.31 337.96,-475.31 C337.96,-475.31 346.14,-471.59 346.14,-471.59 C346.14,-471.59 354.3,-467.82 354.3,-467.82 C354.3,-467.82 362.11,-463.38 362.11,-463.38 C362.11,-463.38 369.92,-458.93 369.92,-458.93 C369.92,-458.93 377.53,-454.17 377.53,-454.17 C377.53,-454.17 384.91,-449.04 384.91,-449.04 C384.91,-449.04 392.29,-443.91 392.29,-443.91 C392.29,-443.91 399.26,-438.24 399.26,-438.24 C399.26,-438.24 406.15,-432.48 406.15,-432.48 C406.15,-432.48 412.92,-426.57 412.92,-426.57 C412.92,-426.57 419.27,-420.22 419.27,-420.22 C419.27,-420.22 425.62,-413.87 425.62,-413.87 C425.62,-413.87 431.61,-407.18 431.61,-407.18 C431.61,-407.18 437.38,-400.29 437.38,-400.29 C437.38,-400.29 443.14,-393.39 443.14,-393.39 C443.14,-393.39 448.27,-386.01 448.27,-386.01 C448.27,-386.01 453.4,-378.64 453.4,-378.64 C453.4,-378.64 458.26,-371.09 458.26,-371.09 C458.26,-371.09 462.71,-363.28 462.71,-363.28 C462.71,-363.28 467.16,-355.47 467.16,-355.47 C467.16,-355.47 471.03,-347.37 471.03,-347.37 C471.03,-347.37 474.75,-339.19 474.75,-339.19 C474.75,-339.19 478.34,-330.95 478.34,-330.95 C478.34,-330.95 481.28,-322.46 481.28,-322.46 C481.28,-322.46 484.21,-313.97 484.21,-313.97 C484.21,-313.97 486.72,-305.35 486.72,-305.35 C486.72,-305.35 488.84,-296.62 488.84,-296.62 C488.84,-296.62 490.96,-287.88 490.96,-287.88 C490.96,-287.88 492.33,-279.01 492.33,-279.01 C492.33,-279.01 493.59,-270.11 493.59,-270.11 C493.59,-270.11 494.69,-261.2 494.69,-261.2 C494.69,-261.2 495.07,-252.22 495.07,-252.22 C495.07,-252.22 495.44,-243.24 495.44,-243.24 C495.44,-243.24 495.41,-234.27 495.41,-234.27 C495.41,-234.27 494.88,-225.29 494.88,-225.29 C494.88,-225.29 494.35,-216.32 494.35,-216.32 C494.35,-216.32 493.22,-207.42 493.22,-207.42 C493.22,-207.42 491.79,-198.55 491.79,-198.55 C491.79,-198.55 490.36,-189.68 490.36,-189.68 C490.36,-189.68 488.19,-180.96 488.19,-180.96 C488.19,-180.96 485.88,-172.28 485.88,-172.28 C485.88,-172.28 483.56,-163.6 483.56,-163.6 C483.56,-163.6 480.48,-155.16 480.48,-155.16 C480.48,-155.16 477.31,-146.75 477.31,-146.75 C477.31,-146.75 474.14,-138.34 474.14,-138.34 C474.14,-138.34 470.62,-130.07 470.62,-130.07 C470.62,-130.07 467.04,-121.83 467.04,-121.83 C467.04,-121.83 463.46,-113.59 463.46,-113.59 C463.46,-113.59 459.88,-105.35 459.88,-105.35 C459.88,-105.35 456.54,-97.01 456.54,-97.01 C456.54,-97.01 453.37,-88.6 453.37,-88.6 C453.37,-88.6 450.21,-80.19 450.21,-80.19 C450.21,-80.19 447.68,-71.57 447.68,-71.57 C447.68,-71.57 445.36,-62.89 445.36,-62.89 C445.36,-62.89 443.04,-54.21 443.04,-54.21 C443.04,-54.21 441.54,-45.35 441.54,-45.35 C441.54,-45.35 440.09,-36.48 440.09,-36.48 C440.09,-36.48 438.78,-27.6 438.78,-27.6 C438.78,-27.6 438.19,-18.63 438.19,-18.63 C438.19,-18.63 437.61,-9.66 437.61,-9.66 C437.61,-9.66 437.36,-0.69 437.36,-0.69 C437.36,-0.69 437.65,8.29 437.65,8.29 C437.65,8.29 437.95,17.27 437.95,17.27 C437.95,17.27 438.77,26.21 438.77,26.21 C438.77,26.21 439.94,35.12 439.94,35.12 C439.94,35.12 441.11,44.03 441.11,44.03 C441.11,44.03 442.99,52.81 442.99,52.81 C442.99,52.81 445.02,61.57 445.02,61.57 C445.02,61.57 447.07,70.31 447.07,70.31 C447.07,70.31 449.82,78.87 449.82,78.87 C449.82,78.87 452.65,87.4 452.65,87.4 C452.65,87.4 455.96,95.75 455.96,95.75 C455.96,95.75 459.33,104.08 459.33,104.08 C459.33,104.08 462.91,112.32 462.91,112.32 C462.91,112.32 466.49,120.57 466.49,120.57 C466.49,120.57 470.07,128.81 470.07,128.81 C470.07,128.81 473.65,137.05 473.65,137.05 C473.65,137.05 476.82,145.46 476.82,145.46 C476.82,145.46 479.99,153.87 479.99,153.87 C479.99,153.87 483.17,162.28 483.17,162.28 C483.17,162.28 485.52,170.94 485.52,170.94 C485.52,170.94 487.84,179.63 487.84,179.63 C487.84,179.63 490.14,188.31 490.14,188.31 C490.14,188.31 491.57,197.18 491.57,197.18 C491.57,197.18 493,206.06 493,206.06 C493,206.06 494.27,214.95 494.27,214.95 C494.27,214.95 494.8,223.92 494.8,223.92 C494.8,223.92 495.33,232.89 495.33,232.89 C495.33,232.89 495.5,241.86 495.5,241.86 C495.5,241.86 495.12,250.84 495.12,250.84 C495.12,250.84 494.75,259.82 494.75,259.82 C494.75,259.82 493.78,268.74 493.78,268.74 C493.78,268.74 492.52,277.64 492.52,277.64 C492.52,277.64 491.27,286.54 491.27,286.54 C491.27,286.54 489.16,295.27 489.16,295.27 C489.16,295.27 487.05,304.01 487.05,304.01 C487.05,304.01 484.66,312.66 484.66,312.66 C484.66,312.66 481.73,321.16 481.73,321.16 C481.73,321.16 478.79,329.65 478.79,329.65 C478.79,329.65 475.32,337.93 475.32,337.93 C475.32,337.93 471.6,346.11 471.6,346.11 C471.6,346.11 467.84,354.27 467.84,354.27 C467.84,354.27 463.39,362.08 463.39,362.08 C463.39,362.08 458.94,369.89 458.94,369.89 C458.94,369.89 454.19,377.5 454.19,377.5 C454.19,377.5 449.06,384.88 449.06,384.88 C449.06,384.88 443.93,392.26 443.93,392.26 C443.93,392.26 438.26,399.23 438.26,399.23 C438.26,399.23 432.5,406.12 432.5,406.12 C432.5,406.12 426.6,412.89 426.6,412.89 C426.6,412.89 420.24,419.24 420.24,419.24 C420.24,419.24 413.89,425.6 413.89,425.6 C413.89,425.6 407.2,431.59 407.2,431.59 C407.2,431.59 400.31,437.36 400.31,437.36 C400.31,437.36 393.42,443.12 393.42,443.12 C393.42,443.12 386.04,448.25 386.04,448.25 C386.04,448.25 378.66,453.38 378.66,453.38 C378.66,453.38 371.11,458.24 371.11,458.24 C371.11,458.24 363.31,462.69 363.31,462.69 C363.31,462.69 355.5,467.14 355.5,467.14 C355.5,467.14 347.4,471.02 347.4,471.02 C347.4,471.02 339.22,474.73 339.22,474.73 C339.22,474.73 330.99,478.33 330.99,478.33 C330.99,478.33 322.49,481.27 322.49,481.27 C322.49,481.27 314,484.2 314,484.2 C314,484.2 305.38,486.71 305.38,486.71 C305.38,486.71 296.65,488.83 296.65,488.83 C296.65,488.83 287.91,490.95 287.91,490.95 C287.91,490.95 279.04,492.33 279.04,492.33 C279.04,492.33 270.14,493.59 270.14,493.59 C270.14,493.59 261.23,494.69 261.23,494.69 C261.23,494.69 252.25,495.07 252.25,495.07 C252.25,495.07 243.28,495.44 243.28,495.44 C243.28,495.44 234.3,495.41 234.3,495.41 C234.3,495.41 225.33,494.88 225.33,494.88 C225.33,494.88 216.36,494.35 216.36,494.35 C216.36,494.35 207.45,493.23 207.45,493.23 C207.45,493.23 198.58,491.8 198.58,491.8 C198.58,491.8 189.71,490.37 189.71,490.37 C189.71,490.37 180.99,488.21 180.99,488.21 C180.99,488.21 172.31,485.89 172.31,485.89 C172.31,485.89 163.63,483.57 163.63,483.57 C163.63,483.57 155.19,480.5 155.19,480.5 C155.19,480.5 146.78,477.32 146.78,477.32 C146.78,477.32 138.37,474.15 138.37,474.15 C138.37,474.15 130.11,470.63 130.11,470.63 C130.11,470.63 121.86,467.06 121.86,467.06 C121.86,467.06 113.62,463.48 113.62,463.48 C113.62,463.48 105.38,459.9 105.38,459.9 C105.38,459.9 97.04,456.56 97.04,456.56 C97.04,456.56 88.63,453.39 88.63,453.39 C88.63,453.39 80.22,450.22 80.22,450.22 C80.22,450.22 71.6,447.7 71.6,447.7 C71.6,447.7 62.92,445.37 62.92,445.37 C62.92,445.37 54.24,443.05 54.24,443.05 C54.24,443.05 45.38,441.55 45.38,441.55 C45.38,441.55 36.52,440.1 36.52,440.1 C36.52,440.1 27.63,438.78 27.63,438.78 C27.63,438.78 18.66,438.2 18.66,438.2 C18.66,438.2 9.7,437.61 9.7,437.61 C9.7,437.61 0.72,437.36 0.72,437.36 C0.72,437.36 -8.26,437.65 -8.26,437.65 C-8.26,437.65 -17.24,437.95 -17.24,437.95 C-17.24,437.95 -26.18,438.77 -26.18,438.77 C-26.18,438.77 -35.09,439.94 -35.09,439.94 C-35.09,439.94 -44,441.1 -44,441.1 C-44,441.1 -52.78,442.98 -52.78,442.98 C-52.78,442.98 -61.53,445.02 -61.53,445.02 C-61.53,445.02 -70.28,447.07 -70.28,447.07 C-70.28,447.07 -78.84,449.81 -78.84,449.81 C-78.84,449.81 -87.37,452.64 -87.37,452.64 C-87.37,452.64 -95.72,455.95 -95.72,455.95 C-95.72,455.95 -104.05,459.32 -104.05,459.32 C-104.05,459.32 -112.29,462.9 -112.29,462.9 C-112.29,462.9 -120.53,466.48 -120.53,466.48 C-120.53,466.48 -128.78,470.06 -128.78,470.06 C-128.78,470.06 -137.02,473.63 -137.02,473.63 C-137.02,473.63 -145.43,476.81 -145.43,476.81 C-145.43,476.81 -153.84,479.98 -153.84,479.98 C-153.84,479.98 -162.24,483.15 -162.24,483.15 C-162.24,483.15 -170.91,485.52 -170.91,485.52 C-170.91,485.52 -179.59,487.83 -179.59,487.83 C-179.59,487.83 -188.28,490.13 -188.28,490.13 C-188.28,490.13 -197.15,491.56 -197.15,491.56 C-197.15,491.56 -206.02,492.99 -206.02,492.99 C-206.02,492.99 -214.91,494.27 -214.91,494.27 C-214.91,494.27 -223.88,494.8 -223.88,494.8 C-223.88,494.8 -232.85,495.33 -232.85,495.33 C-232.85,495.33 -241.83,495.5 -241.83,495.5 C-241.83,495.5 -250.81,495.13 -250.81,495.13 C-250.81,495.13 -259.79,494.75 -259.79,494.75 C-259.79,494.75 -268.71,493.79 -268.71,493.79 C-268.71,493.79 -277.61,492.53 -277.61,492.53 C-277.61,492.53 -286.51,491.27 -286.51,491.27 C-286.51,491.27 -295.24,489.17 -295.24,489.17 C-295.24,489.17 -303.98,487.06 -303.98,487.06 C-303.98,487.06 -312.63,484.67 -312.63,484.67 C-312.63,484.67 -321.12,481.74 -321.12,481.74 C-321.12,481.74 -329.62,478.8 -329.62,478.8 C-329.62,478.8 -337.9,475.33 -337.9,475.33 C-337.9,475.33 -346.08,471.62 -346.08,471.62 C-346.08,471.62 -354.24,467.85 -354.24,467.85 C-354.24,467.85 -362.05,463.41 -362.05,463.41 C-362.05,463.41 -369.86,458.96 -369.86,458.96 C-369.86,458.96 -377.47,454.21 -377.47,454.21 C-377.47,454.21 -384.85,449.08 -384.85,449.08 C-384.85,449.08 -392.23,443.95 -392.23,443.95 C-392.23,443.95 -399.2,438.29 -399.2,438.29 C-399.2,438.29 -406.09,432.52 -406.09,432.52 C-406.09,432.52 -412.86,426.62 -412.86,426.62 C-412.86,426.62 -419.22,420.27 -419.22,420.27 C-419.22,420.27 -425.57,413.91 -425.57,413.91 C-425.57,413.91 -431.57,407.23 -431.57,407.23 C-431.57,407.23 -437.33,400.34 -437.33,400.34 C-437.33,400.34 -443.1,393.44 -443.1,393.44 C-443.1,393.44 -448.23,386.07 -448.23,386.07 C-448.23,386.07 -453.36,378.69 -453.36,378.69 C-453.36,378.69 -458.23,371.15 -458.23,371.15 C-458.23,371.15 -462.67,363.33 -462.67,363.33 C-462.67,363.33 -467.12,355.53 -467.12,355.53 C-467.12,355.53 -471,347.43 -471,347.43 C-471,347.43 -474.72,339.25 -474.72,339.25 C-474.72,339.25 -478.32,331.02 -478.32,331.02 C-478.32,331.02 -481.25,322.52 -481.25,322.52 C-481.25,322.52 -484.19,314.03 -484.19,314.03 C-484.19,314.03 -486.71,305.42 -486.71,305.42 C-486.71,305.42 -488.82,296.68 -488.82,296.68 C-488.82,296.68 -490.94,287.95 -490.94,287.95 C-490.94,287.95 -492.32,279.07 -492.32,279.07 C-492.32,279.07 -493.58,270.18 -493.58,270.18 C-493.58,270.18 -494.69,261.27 -494.69,261.27 C-494.69,261.27 -495.07,252.29 -495.07,252.29 C-495.07,252.29 -495.44,243.31 -495.44,243.31 C-495.44,243.31 -495.42,234.33 -495.42,234.33 C-495.42,234.33 -494.89,225.36 -494.89,225.36 C-494.89,225.36 -494.36,216.39 -494.36,216.39 C-494.36,216.39 -493.23,207.49 -493.23,207.49 C-493.23,207.49 -491.8,198.61 -491.8,198.61 C-491.8,198.61 -490.37,189.74 -490.37,189.74 C-490.37,189.74 -488.22,181.02 -488.22,181.02 C-488.22,181.02 -485.9,172.34 -485.9,172.34 C-485.9,172.34 -483.58,163.66 -483.58,163.66 C-483.58,163.66 -480.51,155.22 -480.51,155.22 C-480.51,155.22 -477.34,146.81 -477.34,146.81 C-477.34,146.81 -474.17,138.41 -474.17,138.41 C-474.17,138.41 -470.65,130.14 -470.65,130.14 C-470.65,130.14 -467.07,121.9 -467.07,121.9 C-467.07,121.9 -463.49,113.65 -463.49,113.65 C-463.49,113.65 -459.91,105.41 -459.91,105.41 C-459.91,105.41 -456.57,97.07 -456.57,97.07 C-456.57,97.07 -453.4,88.66 -453.4,88.66 C-453.4,88.66 -450.23,80.25 -450.23,80.25 C-450.23,80.25 -447.7,71.64 -447.7,71.64 C-447.7,71.64 -445.38,62.96 -445.38,62.96 C-445.38,62.96 -443.06,54.28 -443.06,54.28 C-443.06,54.28 -441.56,45.42 -441.56,45.42 C-441.56,45.42 -440.1,36.55 -440.1,36.55 C-440.1,36.55 -438.78,27.67 -438.78,27.67 C-438.78,27.67 -438.2,18.7 -438.2,18.7 C-438.2,18.7 -437.62,9.73 -437.62,9.73 C-437.62,9.73 -437.36,0.76 -437.36,0.76 C-437.36,0.76 -437.66,-8.22 -437.66,-8.22 C-437.66,-8.22 -437.95,-17.2 -437.95,-17.2 C-437.95,-17.2 -438.77,-26.14 -438.77,-26.14 C-438.77,-26.14 -439.93,-35.05 -439.93,-35.05 C-439.93,-35.05 -441.1,-43.96 -441.1,-43.96 C-441.1,-43.96 -442.98,-52.75 -442.98,-52.75 C-442.98,-52.75 -445.01,-61.5 -445.01,-61.5 C-445.01,-61.5 -447.06,-70.25 -447.06,-70.25 C-447.06,-70.25 -449.8,-78.81 -449.8,-78.81 C-449.8,-78.81 -452.63,-87.33 -452.63,-87.33 C-452.63,-87.33 -455.94,-95.69 -455.94,-95.69 C-455.94,-95.69 -459.31,-104.02 -459.31,-104.02 C-459.31,-104.02 -462.89,-112.26 -462.89,-112.26 C-462.89,-112.26 -466.47,-120.5 -466.47,-120.5 C-466.47,-120.5 -470.05,-128.74 -470.05,-128.74 C-470.05,-128.74 -473.68,-137.12 -473.68,-137.12 C-473.68,-137.12 -476.85,-145.53 -476.85,-145.53 C-476.85,-145.53 -480.03,-153.94 -480.03,-153.94 C-480.03,-153.94 -483.2,-162.34 -483.2,-162.34 C-483.2,-162.34 -485.55,-171.02 -485.55,-171.02 C-485.55,-171.02 -487.86,-179.7 -487.86,-179.7 C-487.86,-179.7 -490.15,-188.39 -490.15,-188.39 C-490.15,-188.39 -491.58,-197.26 -491.58,-197.26 C-491.58,-197.26 -493.01,-206.13 -493.01,-206.13 C-493.01,-206.13 -494.28,-215.02 -494.28,-215.02 C-494.28,-215.02 -494.81,-223.99 -494.81,-223.99 C-494.81,-223.99 -495.33,-232.96 -495.33,-232.96 C-495.33,-232.96 -495.5,-241.94 -495.5,-241.94 C-495.5,-241.94 -495.12,-250.92 -495.12,-250.92 C-495.12,-250.92 -494.75,-259.9 -494.75,-259.9 C-494.75,-259.9 -493.78,-268.82 -493.78,-268.82 C-493.78,-268.82 -492.52,-277.72 -492.52,-277.72 C-492.52,-277.72 -491.26,-286.61 -491.26,-286.61 C-491.26,-286.61 -489.15,-295.35 -489.15,-295.35 C-489.15,-295.35 -487.03,-304.08 -487.03,-304.08 C-487.03,-304.08 -484.64,-312.73 -484.64,-312.73 C-484.64,-312.73 -481.7,-321.23 -481.7,-321.23 C-481.7,-321.23 -478.77,-329.72 -478.77,-329.72 C-478.77,-329.72 -475.29,-338 -475.29,-338 C-475.29,-338 -471.57,-346.18 -471.57,-346.18 C-471.57,-346.18 -467.8,-354.33 -467.8,-354.33 C-467.8,-354.33 -463.36,-362.14 -463.36,-362.14 C-463.36,-362.14 -458.91,-369.95 -458.91,-369.95 C-458.91,-369.95 -454.15,-377.56 -454.15,-377.56 C-454.15,-377.56 -449.02,-384.94 -449.02,-384.94 C-449.02,-384.94 -443.88,-392.32 -443.88,-392.32 C-443.88,-392.32 -438.22,-399.28 -438.22,-399.28 C-438.22,-399.28 -432.45,-406.18 -432.45,-406.18 C-432.45,-406.18 -426.55,-412.94 -426.55,-412.94 C-426.55,-412.94 -420.19,-419.3 -420.19,-419.3 C-420.19,-419.3 -413.84,-425.65 -413.84,-425.65 C-413.84,-425.65 -407.15,-431.64 -407.15,-431.64 C-407.15,-431.64 -400.26,-437.41 -400.26,-437.41 C-400.26,-437.41 -393.36,-443.16 -393.36,-443.16 C-393.36,-443.16 -385.98,-448.29 -385.98,-448.29 C-385.98,-448.29 -378.6,-453.43 -378.6,-453.43 C-378.6,-453.43 -371.05,-458.28 -371.05,-458.28 C-371.05,-458.28 -363.24,-462.73 -363.24,-462.73 C-363.24,-462.73 -355.43,-467.18 -355.43,-467.18 C-355.43,-467.18 -347.33,-471.05 -347.33,-471.05 C-347.33,-471.05 -339.15,-474.76 -339.15,-474.76 C-339.15,-474.76 -330.92,-478.35 -330.92,-478.35 C-330.92,-478.35 -322.42,-481.29 -322.42,-481.29 C-322.42,-481.29 -313.93,-484.23 -313.93,-484.23 C-313.93,-484.23 -305.31,-486.73 -305.31,-486.73 C-305.31,-486.73 -296.58,-488.85 -296.58,-488.85 C-296.58,-488.85 -287.85,-490.97 -287.85,-490.97 C-287.85,-490.97 -278.97,-492.34 -278.97,-492.34 C-278.97,-492.34 -270.07,-493.6 -270.07,-493.6 C-270.07,-493.6 -261.16,-494.7 -261.16,-494.7 C-261.16,-494.7 -252.18,-495.07 -252.18,-495.07 C-252.18,-495.07 -243.2,-495.44 -243.2,-495.44 C-243.2,-495.44 -234.23,-495.41 -234.23,-495.41 C-234.23,-495.41 -225.26,-494.88 -225.26,-494.88 C-225.26,-494.88 -216.29,-494.35 -216.29,-494.35 C-216.29,-494.35 -207.38,-493.22 -207.38,-493.22 C-207.38,-493.22 -198.51,-491.79 -198.51,-491.79 C-198.51,-491.79 -189.64,-490.36 -189.64,-490.36 C-189.64,-490.36 -180.92,-488.19 -180.92,-488.19 C-180.92,-488.19 -172.24,-485.87 -172.24,-485.87 C-172.24,-485.87 -163.56,-483.56 -163.56,-483.56 C-163.56,-483.56 -155.12,-480.47 -155.12,-480.47 C-155.12,-480.47 -146.72,-477.3 -146.72,-477.3 C-146.72,-477.3 -138.31,-474.13 -138.31,-474.13 C-138.31,-474.13 -130.04,-470.61 -130.04,-470.61 C-130.04,-470.61 -121.8,-467.03 -121.8,-467.03 C-121.8,-467.03 -113.55,-463.45 -113.55,-463.45 C-113.55,-463.45 -105.31,-459.87 -105.31,-459.87 C-105.31,-459.87 -96.97,-456.53 -96.97,-456.53 C-96.97,-456.53 -88.56,-453.37 -88.56,-453.37 C-88.56,-453.37 -80.15,-450.2 -80.15,-450.2 C-80.15,-450.2 -71.53,-447.68 -71.53,-447.68 C-71.53,-447.68 -62.85,-445.36 -62.85,-445.36 C-62.85,-445.36 -54.17,-443.04 -54.17,-443.04 C-54.17,-443.04 -45.31,-441.54 -45.31,-441.54 C-45.31,-441.54 -36.44,-440.09 -36.44,-440.09 C-36.44,-440.09 -27.56,-438.78 -27.56,-438.78 C-27.56,-438.78 -18.59,-438.19 -18.59,-438.19 C-18.59,-438.19 -9.62,-437.61 -9.62,-437.61 C-9.62,-437.61 -0.65,-437.37 -0.65,-437.37c " /> - </group> - </group> - <group android:name="time_group" /> - </vector> - </aapt:attr> -</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/touchpad_tutorial_apps_icon.xml b/packages/SystemUI/res/drawable/touchpad_tutorial_apps_icon.xml new file mode 100644 index 000000000000..5f9d4212e440 --- /dev/null +++ b/packages/SystemUI/res/drawable/touchpad_tutorial_apps_icon.xml @@ -0,0 +1,25 @@ +<!-- + ~ Copyright (C) 2025 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:height="24dp" + android:width="24dp" + android:autoMirrored="true" + android:viewportHeight="960" + android:viewportWidth="960"> + <path android:fillColor="@android:color/white" + android:pathData="M240,800q-33,0 -56.5,-23.5T160,720q0,-33 23.5,-56.5T240,640q33,0 56.5,23.5T320,720q0,33 -23.5,56.5T240,800ZM480,800q-33,0 -56.5,-23.5T400,720q0,-33 23.5,-56.5T480,640q33,0 56.5,23.5T560,720q0,33 -23.5,56.5T480,800ZM720,800q-33,0 -56.5,-23.5T640,720q0,-33 23.5,-56.5T720,640q33,0 56.5,23.5T800,720q0,33 -23.5,56.5T720,800ZM240,560q-33,0 -56.5,-23.5T160,480q0,-33 23.5,-56.5T240,400q33,0 56.5,23.5T320,480q0,33 -23.5,56.5T240,560ZM480,560q-33,0 -56.5,-23.5T400,480q0,-33 23.5,-56.5T480,400q33,0 56.5,23.5T560,480q0,33 -23.5,56.5T480,560ZM720,560q-33,0 -56.5,-23.5T640,480q0,-33 23.5,-56.5T720,400q33,0 56.5,23.5T800,480q0,33 -23.5,56.5T720,560ZM240,320q-33,0 -56.5,-23.5T160,240q0,-33 23.5,-56.5T240,160q33,0 56.5,23.5T320,240q0,33 -23.5,56.5T240,320ZM480,320q-33,0 -56.5,-23.5T400,240q0,-33 23.5,-56.5T480,160q33,0 56.5,23.5T560,240q0,33 -23.5,56.5T480,320ZM720,320q-33,0 -56.5,-23.5T640,240q0,-33 23.5,-56.5T720,160q33,0 56.5,23.5T800,240q0,33 -23.5,56.5T720,320Z"/> +</vector> diff --git a/packages/SystemUI/res/layout/contextual_edu_dialog.xml b/packages/SystemUI/res/layout/contextual_edu_dialog.xml index 09aa8daa217e..e83d4902d512 100644 --- a/packages/SystemUI/res/layout/contextual_edu_dialog.xml +++ b/packages/SystemUI/res/layout/contextual_edu_dialog.xml @@ -29,7 +29,7 @@ android:layout_height="wrap_content" android:contentDescription="@null" android:importantForAccessibility="no" - android:paddingRight="16dp" /> + android:paddingHorizontal="16dp" /> <TextView android:id="@+id/edu_message" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 0e8b2d53598e..5e7d9c4a041b 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goeie toestand"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding is beskikbaar"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelliet-SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Noodoproepe of SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"geen sein nie"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"een staaf"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"gaan by toestel in"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om oop te maak"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Stawing word vereis. Raak die vingerafdruksensor om te staaf."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Oproep aan die gang"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiele data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Gekoppel"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tydelik gekoppel"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Kortpadsleutels"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pasmaak kortpadsleutels"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Pasmaak kortpaaie"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Verwyder kortpad?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Stel terug na verstek?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Druk sleutel om kortpad toe te wys"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Sleutelkombinasie is reeds in gebruik. Probeer ’n ander sleutel."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Kortpad kan nie gestel word nie."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Voeg kortpad by"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Vee kortpad uit"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeer met jou sleutelbord"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer kortpadsleutels"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeer met jou raakpaneel"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 15286a6aaea2..d969525b7c4a 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ሳተላይት፣ ጥሩ ግንኙነት"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ሳተላይት፣ ግንኙነት አለ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ሳተላይት ኤስኦኤስ"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"የአደጋ ጥሪዎች ወይም ኤስኦኤስ"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>፣ <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>።"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ምንም ምልክት የለም"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"አንድ አሞሌ"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"መሣሪያን ያስገቡ"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ለመክፈት የጣት አሻራ ይጠቀሙ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ማረጋገጥ ያስፈልጋል። ለማረጋገጥ የጣት አሻራ ዳሳሹን ይንኩ።"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"እየተካሄደ ያለ ጥሪ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"የተንቀሳቃሽ ስልክ ውሂብ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ተገናኝቷል"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"በጊዜያዊነት ተገናኝቷል"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"የአሁን መተግበሪያ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"የቁልፍ ሰሌዳ አቋራጮች"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"የቁልፍ ሰሌዳ አቋራጮችን ያብጁ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"አቋራጮችን ያብጁ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"አቋራጭ ይወገድ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ወደ ነባሪ ዳግም ይጀመር?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"አቋራጭ ለመመደብ ቁልፍ ይጫኑ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"የቁልፍ ጥምረት አስቀድሞ በሥራ ላይ ነው። ሌላ ቁልፍ ይሞክሩ።"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"አቋራጩ ሊቀናበር አይችልም።"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"አቋራጭ አክል"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"አቋረጭ ሰርዝ"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"የቁልፍ ሰሌዳዎን በመጠቀም ያስሱ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"የቁልፍ ሰሌዳ አቋራጮችን ይወቁ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"የመዳሰሻ ሰሌዳዎን በመጠቀም ያስሱ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index d68c43281908..d46df1d8b348 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"قمر صناعي، الاتصال جيد"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"قمر صناعي، الاتصال متوفّر"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"اتصالات الطوارئ بالقمر الصناعي"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"مكالمات الطوارئ أو ميزة \"اتصالات طوارئ بالقمر الصناعي\""</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"\"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>\"، <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ما مِن أشرطة إشارة"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"شريط إشارة واحد"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"الدخول إلى الجهاز"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"يمكنك استخدام بصمة الإصبع للفتح"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"المصادقة مطلوبة. المس مستشعر بصمات الإصبع للمصادقة."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"مكالمة جارية"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"بيانات الجوّال"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"متصلة بالإنترنت"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"متصلة مؤقتًا"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"التطبيق الحالي"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"اختصارات لوحة المفاتيح"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"تخصيص اختصارات لوحة المفاتيح"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"هل تريد إزالة هذا الاختصار؟"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"يُرجى تأكيد إعادة الضبط على الإعدادات التلقائية"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"اضغط على مفتاح لتخصيص الاختصار"</string> @@ -1465,6 +1466,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"يتم حاليًا استخدام مجموعة المفاتيح هذه. يُرجى تجربة مفتاح آخر."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"تعذَّر ضبط الاختصار."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"إضافة اختصار"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"حذف الاختصار"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"التنقّل باستخدام لوحة المفاتيح"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"تعرَّف على اختصارات لوحة المفاتيح"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"التنقّل باستخدام لوحة اللمس"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 4c4579f8e42d..ff5e2106a8d2 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"উপগ্ৰহ, ভাল সংযোগ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"উপগ্ৰহ, সংযোগ উপলব্ধ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"উপগ্ৰহ SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"জৰুৰীকালীন কল বা SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"কোনো ছিগনেল নাই"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"এডাল দণ্ড"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলিবলৈ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণৰ আৱশ্যক। বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰিবলৈ ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক।"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"চলি থকা কল"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ম’বাইল ডেটা"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"সংযোজিত হৈ আছে"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"অস্থায়ীভাৱে সংযোগ কৰা হৈছে"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বৰ্তমানৰ এপ্"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"কীব’ৰ্ডৰ শ্বৰ্টকাট"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীব’ৰ্ডৰ শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"শ্বৰ্টকাট কাষ্টমাইজ কৰক"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"শ্বৰ্টকাট আঁতৰাবনে?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ডিফ\'ল্ট হিচাপে পুনৰ ৰিছেট কৰিবনে?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"শ্বৰ্টকাটৰ ভূমিকা অৰ্পণ কৰিবলৈ কী টিপক"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"কীৰ মিশ্ৰণ ইতিমধ্যে ব্যৱহাৰ হৈ আছে। অন্য এটা কী ব্যৱহাৰ কৰি চাওক।"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"শ্বৰ্টকাট ছেট কৰিব নোৱাৰি।"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"শ্বৰ্টকাট যোগ দিয়ক"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"শ্বৰ্টকাট মচক"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"কীব’ৰ্ড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীব’ৰ্ডৰ শ্বৰ্টকাটসমূহৰ বিষয়ে জানক"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপোনাৰ টাচ্চপেড ব্যৱহাৰ কৰি নেভিগে’ট কৰক"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 08452d353765..dbeacf0bf277 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Peyk, bağlantı yaxşıdır"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Peyk, bağlantı var"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Təcili peyk bağlantısı"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Təcili zənglər və ya SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"siqnal yoxdur"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"bir zolaq"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz daxil edin"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmaq üçün barmaq izindən istifadə edin"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Doğrulanma tələb olunur. Doğrulamaq üçün barmaq izi sensoruna toxunun."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Davam edən zəng"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Qoşulub"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Müvəqqəti qoşulub"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Cari tətbiq"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatura qısayolları"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatura qısayollarını fərdiləşdirin"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Qısayolları fərdiləşdirin"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Qısayol silinsin?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Defolt vəziyyətə qaytarılsın?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Qısayol təyin etmək üçün düyməni basın"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Düymə kombinasiyası artıq istifadə olunur. Başqa düyməni sınayın."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Qısayol ayarlana bilməz."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Qısayol əlavə edin"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Qısayolu silin"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviaturadan istifadə edərək hərəkət edin"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klaviatura qısayolları haqqında öyrənin"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Taçpeddən istifadə edərək hərəkət edin"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 8d9495a1a4e7..ca01a3d89ebe 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, veza je dobra"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Hitna pomoć preko satelita"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili hitna pomoć"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nema signala"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"jedna crta"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je potvrda identiteta. Dodirnite senzor za otisak prsta da biste potvrdili identitet."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv je u toku"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelna aplikacija"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tasterske prečice"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite tasterske prečice"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Prilagodite prečice"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite da uklonite prečicu?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite da resetujete na podrazumevano?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite taster da biste dodelili prečicu"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tastera se već koristi. Probajte sa drugim tasterom."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Podešavanje prečice nije uspelo."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Dodajte prečicu"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Izbrišite prečicu"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tasterskim prečicama"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću tačpeda"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index 3431862c77fc..40d78c20859b 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спадарожнікавая сувязь, добрае падключэнне"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спадарожнікавая сувязь, падключэнне даступнае"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Экстраннае спадарожнікавае падключэнне"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Экстранныя выклікі або экстраннае спадарожнікавае падключэнне"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"няма сігналу"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"адзiн слупок"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"адкрыць галоўны экран прылады"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Каб адкрыць, скарыстайце адбітак пальца"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Патрабуецца аўтэнтыфікацыя. Дакраніцеся да сканера адбіткаў пальцаў."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Актыўны выклік"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мабільная перадача даных"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Падключана"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Падключана часова"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Бягучая праграма"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Спалучэнні клавіш"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Наладзіць спалучэнні клавіш"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Наладзіць спалучэнні клавіш"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Выдаліць спалучэнне клавіш?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Скінуць налады да стандартных?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Націсніце клавішу, каб прызначыць спалучэнне клавіш"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Гэта спалучэнне клавіш ужо выкарыстоўваецца. Паспрабуйце іншую клавішу."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Не ўдаецца наладзіць спалучэнне клавіш."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Дадаць ярлык"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Выдаліць спалучэнне клавіш"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігацыя з дапамогай клавіятуры"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Азнаёмцеся са спалучэннямі клавіш"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігацыя з дапамогай сэнсарнай панэлі"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 1128d03595e1..95037ab4d29e 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, добра връзка"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, налице е връзка"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS чрез сателит"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Спешни обаждания или SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"няма сигнал"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"една чертичка"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"вход в устройството"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Използвайте отпечатък за отваряне"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Изисква се удостоверяване на самоличността. За целта докоснете сензора за отпечатъци."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Текущо обаждане"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни данни"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Свързано"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Установена е временна връзка"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Текущо приложение"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Клавишни комбинации"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Персонализиране на клавишните комбинации"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Персонализиране на преките пътища"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Да се премахне ли клавишната комбинация?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Да се възстановят ли стандартните настройки?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Натиснете клавиш, за да зададете клавишна комбинация"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Клавишната комбинация вече се използва. Опитайте с друг клавиш."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Прекият път не може да се зададе."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Добавяне на пряк път"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Изтриване на прекия път"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигирайте посредством клавиатурата си"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете за клавишните комбинации"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигирайте посредством сензорния панел"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 23a693b9840e..73eddf28bbed 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"স্যাটেলাইট, ভালো কানেকশন"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"স্যাটেলাইট, কানেকশন উপলভ্য আছে"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"স্যাটেলাইট SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"জরুরি কল বা SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>।"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"কোনও সিগন্যাল নেই"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"একটি বার"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলতে ফিঙ্গারপ্রিন্ট ব্যবহার করুন"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"যাচাইকরণ করতে হবে। যাচাইকরণ করতে আঙুলের ছাপের সেন্সরে টাচ করুন।"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"চালু থাকা কল"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"মোবাইল ডেটা"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"কানেক্ট করা আছে"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"সাময়িকভাবে কানেক্ট করা হয়েছে"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"বর্তমান অ্যাপ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"কীবোর্ড শর্টকাট"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"কীবোর্ড শর্টকাট কাস্টমাইজ করুন"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"শর্টকাট কাস্টমাইজ করুন"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"শর্টকাট সরাবেন?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ডিফল্ট শর্টকার্ট আবার রিসেট করতে চান?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"শর্টকাট অ্যাসাইন করতে কী প্রেস করুন"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"কী কম্বিনেশন আগে থেকে ব্যবহার হচ্ছে। অন্য কী ব্যবহার করে দেখুন।"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"শর্টকাট সেট করা যায়নি।"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"শর্টকাট যোগ করুন"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"শর্টকাট মুছুন"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"আপনার কীবোর্ড ব্যবহার করে নেভিগেট করুন"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"কীবোর্ড শর্টকাট সম্পর্কে জানুন"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"আপনার টাচপ্যাড ব্যবহার করে নেভিগেট করুন"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index d7b3f60edb03..c16627f86820 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -348,7 +348,7 @@ <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Neimenovani uređaj"</string> <string name="quick_settings_cast_detail_empty_text" msgid="2846282280014617785">"Nema dostupnih uređaja"</string> <string name="quick_settings_cast_no_network" msgid="3863016850468559522">"Nema WiFi-ja ni Ethernet veze"</string> - <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvjetljenje"</string> + <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Osvijetljenost"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"Inverzija boja"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"Ispravka boja"</string> <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"Veličina fonta"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Hitna pomoć putem satelita"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili pomoć"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nema signala"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"jedna crtica"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"pristup uređaju"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je autentifikacija. Dodirnite senzor za otisak prsta da autentificirate."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv u toku"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Prijenos podataka na mobilnoj mreži"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Prečice na tastaturi"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodite prečice na tastaturi"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Prilagodite prečice"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ukloniti prečicu?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vratiti na zadano?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da dodijelite prečicu"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ta se kombinacija tipki već koristi. Pokušajte s drugom tipkom."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Prečica se ne može postaviti."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Dodavanje prečice"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Brisanje prečice"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tastature"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o prečicama tastature"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 09f63c551f01..43ba8fac3dad 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satèl·lit, bona connexió"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satèl·lit, connexió disponible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS per satèl·lit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Trucades d\'emergència o SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"no hi ha senyal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"una barra"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"accedir al dispositiu"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilitza l\'empremta digital per obrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticació necessària. Toca el sensor d\'empremtes digitals per autenticar-te."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Trucada en curs"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dades mòbils"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connectat"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connexió temporal"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicació actual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tecles de drecera"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalitza les tecles de drecera"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalitza les dreceres"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vols suprimir la drecera?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vols restablir els valors predeterminats?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prem la tecla per assignar la drecera"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinació de tecles ja s\'està utilitzant. Prova-ho amb una altra tecla."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"No es pot configurar la drecera."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Afegeix una drecera"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Suprimeix la drecera"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega amb el teclat"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprèn les tecles de drecera"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega amb el ratolí tàctil"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 07587641802a..17945a3856d6 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobré připojení"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, připojení je k dispozici"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS přes satelit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Tísňová volání nebo SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"není signál"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"jedna čárka"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"zadáte zařízení"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"K otevření použijte otisk prstu"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Je vyžadováno ověření. Dotkněte se snímače otisků prstů."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Probíhající hovor"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilní data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Připojeno"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasně připojeno"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuální aplikace"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové zkratky"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Přizpůsobení klávesových zkratek"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Odstranit zkratku?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Resetovat do výchozího nastavení?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Nastavte zkratku stisknutím klávesy"</string> @@ -1465,6 +1466,10 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinace kláves se už používá. Použijte jinou klávesu."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Zkratku není možné nastavit."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <!-- no translation found for shortcut_helper_add_shortcut_button_label (7655779534665954910) --> + <skip /> + <!-- no translation found for shortcut_helper_delete_shortcut_button_label (3148773472696137052) --> + <skip /> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigujte pomocí klávesnice"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte se klávesové zkratky"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigujte pomocí touchpadu"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index bcf93657caa7..1f8c8659b9cf 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit – god forbindelse"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit – forbindelsen er tilgængelig"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-meldinger via satellit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nødopkald eller SOS-meldinger via satellit"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"intet signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"én bjælke"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"få adgang til enheden"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Brug fingeraftryk for at åbne"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Godkendelse er påkrævet. Sæt fingeren på fingeraftrykssensoren for at godkende."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Igangværende opkald"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Forbundet"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Midlertidigt forbundet"</string> @@ -1437,13 +1437,13 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuel app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tastaturgenveje"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpas tastaturgenveje"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Tilpas genveje"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Skal genvejen fjernes?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vil du nulstille til standard?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tryk på en tast for at tildele genvej"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Denne handling sletter din tilpassede genvej permanent."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Denne handling sletter alle dine tilpassede genveje permanent."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Genveje til søgning"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Søg efter genveje"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Der er ingen søgeresultater"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikon for Skjul"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikon for handlingstast eller metatast"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tastekombinationen er allerede i brug. Prøv en anden tast."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Genvejen kan ikke konfigureres."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Tilføj genvej"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Slet genvej"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger ved hjælp af dit tastatur"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Se tastaturgenveje"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger ved hjælp af din touchplade"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 670f5a712c4a..213955839a71 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, Verbindung gut"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, Verbindung verfügbar"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Notruf über Satellit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Notrufe oder SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"kein Empfang"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ein Balken"</string> @@ -871,7 +872,7 @@ <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Tastenkombinationen für die Eingabe werden angezeigt"</string> <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Tastenkombinationen zum Öffnen von Apps werden angezeigt"</string> <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Tastenkombinationen für die aktuelle App werden angezeigt"</string> - <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Benachrichtigungen ansehen"</string> + <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Benachrichtigungen ansehen"</string> <string name="group_system_full_screenshot" msgid="5742204844232667785">"Screenshot erstellen"</string> <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Tastenkürzel anzeigen"</string> <string name="group_system_go_back" msgid="2730322046244918816">"Zurück"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"Eingeben des Geräts"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Mit Fingerabdruck öffnen"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentifizierung erforderlich. Tippe dazu einfach auf den Fingerabdrucksensor."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktiver Anruf"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile Daten"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Verbunden"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Vorübergehend verbunden"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuelle App"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tastenkürzel"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tastenkürzel anpassen"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Tastenkombinationen anpassen"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Tastaturkürzel entfernen?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Auf Standardeinstellung zurücksetzen?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Drücke eine Taste, um das Tastaturkürzel einzurichten"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Diese Tastenkombination wird bereits verwendet. Versuche es mit einer anderen Taste."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Die Tastenkombination kann nicht festgelegt werden."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Verknüpfung hinzufügen"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Verknüpfung löschen"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigation mit der Tastatur"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informationen zu Tastenkombinationen"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigation mit dem Touchpad"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 31e356797f68..589298ea616b 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Δορυφορική, καλή σύνδεση"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Δορυφορική, διαθέσιμη σύνδεση"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Δορυφορικό SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Κλήσεις έκτακτης ανάγκης ή SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"δεν υπάρχει σήμα"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"μία γραμμή"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"εισαγωγή συσκευής"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Χρήση δακτυλικού αποτυπώματος για άνοιγμα"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Απαιτείται έλεγχος ταυτότητας. Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων για έλεγχο ταυτότητας."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Κλήση σε εξέλιξη"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Δεδομένα κινητής τηλεφωνίας"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Συνδέθηκε"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Προσωρινή σύνδεση"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Τρέχουσα εφαρμογή"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Συντομεύσεις πληκτρολογίου"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Προσαρμογή συντομεύσεων πληκτρολογίου"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Προσαρμογή συντομεύσεων"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Κατάργηση συντόμευσης;"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Επαναφορά στις προεπιλογές;"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Πατήστε το πλήκτρο για ανάθεση της συντόμευσης"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ο συνδυασμός πλήκτρων χρησιμοποιείται ήδη. Δοκιμάστε άλλο πλήκτρο."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Δεν είναι δυνατή η ρύθμιση της συντόμευσης."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Προσθήκη συντόμευσης"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Διαγραφή συντόμευσης"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Πλοήγηση με το πληκτρολόγιο"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Μάθετε συντομεύσεις πληκτρολογίου"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Πλοήγηση με την επιφάνεια αφής"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 30eb21f9308f..f31e51f7f3da 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"No signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"one bar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Customise shortcuts"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remove shortcut?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Reset back to default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Press key to assign shortcut"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Key combination already in use. Try another key."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shortcut cannot be set."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Add shortcut"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Delete shortcut"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 4b4b7b8e4575..be09504a5cd6 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"no signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"one bar"</string> @@ -1436,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current App"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customize keyboard shortcuts"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Customize shortcuts"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remove shortcut?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Reset back to default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Press key to assign shortcut"</string> @@ -1464,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Key combination already in use. Try another key."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shortcut cannot be set."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Add shortcut"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Delete shortcut"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 30eb21f9308f..f31e51f7f3da 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"No signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"one bar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Customise shortcuts"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remove shortcut?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Reset back to default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Press key to assign shortcut"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Key combination already in use. Try another key."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shortcut cannot be set."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Add shortcut"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Delete shortcut"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 30eb21f9308f..f31e51f7f3da 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, good connection"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, connection available"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Emergency calls or SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"No signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"one bar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use fingerprint to open"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentication required. Touch the fingerprint sensor to authenticate."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ongoing call"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connected"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporarily connected"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Current app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Keyboard shortcuts"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Customise keyboard shortcuts"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Customise shortcuts"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remove shortcut?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Reset back to default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Press key to assign shortcut"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Key combination already in use. Try another key."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shortcut cannot be set."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Add shortcut"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Delete shortcut"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigate using your keyboard"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Learn keyboards shortcuts"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigate using your touchpad"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 2b3c54d9e280..dacea9ff1b61 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Llamadas de emergencia o SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"sin señal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"una barra"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ingresar al dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella dactilar para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Se requiere de una autenticación. Toca el sensor de huellas dactilares para autenticarte."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Llamada en curso"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móviles"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conexión establecida"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectado temporalmente"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App actual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personaliza las combinaciones de teclas"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar combinaciones de teclas"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"¿Quieres quitar la combinación?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"¿Quieres restablecer la configuración predeterminada?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Presiona una tecla para asignar la combinación"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinación de teclas ya está en uso. Prueba con otra."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"No se puede establecer la combinación de teclas."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Agregar combinación de teclas"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Borrar combinación de teclas"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega con el teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega con el panel táctil"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 69fab5ac89db..1799055627c1 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, buena conexión"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión disponible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Llamadas de emergencia o SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"no hay señal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"una barra"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"acceder al dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa la huella digital para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticación obligatoria. Toca el sensor de huellas digitales para autenticarte."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Llamada en curso"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móviles"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectada temporalmente"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación en uso"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Combinaciones de teclas"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar las combinaciones de teclas"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar combinaciones de teclas"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"¿Eliminar combinación de teclas?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"¿Restablecer valores predeterminados?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pulsa una tecla para asignar una combinación de teclas"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinación de teclas ya se está usando. Prueba con otra tecla."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"No se puede configurar la combinación de teclas."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Añadir combinación de teclas"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Eliminar combinación de teclas"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Desplázate con el teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende combinaciones de teclas"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Desplázate con el panel táctil"</string> @@ -1517,7 +1519,7 @@ <string name="overview_edu_notification_content" msgid="3578204677648432500">"Desliza hacia arriba con tres dedos y mantén pulsado. Toca para aprender a usar más gestos."</string> <string name="all_apps_edu_notification_title" msgid="372262997265569063">"Usa el teclado para ver todas las aplicaciones"</string> <string name="all_apps_edu_notification_content" msgid="3255070575694025585">"Pulsa la tecla de acción en cualquier momento. Toca para aprender a usar más gestos."</string> - <string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"La atenuación extra ahora forma parte del control deslizante de brillo"</string> + <string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"La atenuación extra ahora forma parte del control deslizante de brillo"</string> <string name="accessibility_deprecate_extra_dim_dialog_description" msgid="4453123359258743230">"Ahora puedes atenuar aún más tu pantalla reduciendo el nivel de brillo.\n\nComo esta función ahora forma parte del control deslizante de brillo, se van a quitar los accesos directos de atenuación extra."</string> <string name="accessibility_deprecate_extra_dim_dialog_button" msgid="3947537827396916005">"Eliminar accesos directos de atenuación extra"</string> <string name="accessibility_deprecate_extra_dim_dialog_toast" msgid="165474092660941104">"Accesos directos de atenuación extra eliminados"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 2ba50051b6ab..a91e3dcc7b2f 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliit, hea ühendus"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliit, ühendus on saadaval"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelliit-SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hädaabikõned või SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"signaal puudub"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"üks pulk"</string> @@ -814,7 +815,7 @@ <string name="notification_channel_controls_opened_accessibility" msgid="6111817750774381094">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> märguannete juhtelemendid on avatud"</string> <string name="notification_channel_controls_closed_accessibility" msgid="1561909368876911701">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> märguannete juhtelemendid on suletud"</string> <string name="notification_more_settings" msgid="4936228656989201793">"Rohkem seadeid"</string> - <string name="notification_app_settings" msgid="8963648463858039377">"Kohandamine"</string> + <string name="notification_app_settings" msgid="8963648463858039377">"Kohanda"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Kuva mull"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Eemalda mullid"</string> <string name="notification_menu_accessibility" msgid="8984166825879886773">"<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"seadmesse sisenemiseks"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Kasutage avamiseks sõrmejälge"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Vajalik on autentimine. Puudutage autentimiseks sõrmejäljeandurit."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Käimasolev kõne"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiilne andmeside"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ühendatud"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ajutiselt ühendatud"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Praegune rakendus"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Klaviatuuri otseteed"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klaviatuuri otseteede kohandamine"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Otseteede kohandamine"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Kas soovite otsetee eemaldada?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Kas lähtestada vaikeseadele?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Otsetee lisamiseks vajutage klahvi"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinatsioon on juba kasutusel. Proovige mõnda muud klahvi."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Otseteed ei saa seadistada."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Otsetee lisamine"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Otsetee kustutamine"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeerige klaviatuuri abil"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Õppige klaviatuuri otseteid"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeerige puuteplaadi abil"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 89ec1dda2435..3a3c9cc144a6 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -228,7 +228,7 @@ <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Konfiguratu hatz-marka bidez desblokeatzeko eginbidea"</string> <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Hatz-marka bidez desblokeatzeko eginbidea berriro konfiguratzeko, oraingo hatz-markaren irudiak eta ereduak ezabatu egingo dira lehendabizi.\n\nHaiek ezabatuz gero, hatz-marka bidez desblokeatzeko eginbidea berriro konfiguratu beharko duzu telefonoa hatz-marka erabilita desblokeatzeko edo zeu zarela egiaztatzeko."</string> <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Hatz-marka bidez desblokeatzeko eginbidea berriro konfiguratzeko, oraingo hatz-markaren irudiak eta eredua ezabatu egingo dira lehendabizi.\n\nHaiek ezabatuz gero, hatz-marka bidez desblokeatzeko eginbidea berriro konfiguratu beharko duzu telefonoa hatz-marka erabilita desblokeatzeko edo zeu zarela egiaztatzeko."</string> - <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Ezin izan da konfiguratu hatz-marka bidez desblokeatzeko eginbidea. Berriro saiatzeko, joan ezarpenetara."</string> + <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Ezin izan da konfiguratu hatz-marka bidez desblokeatzeko eginbidea. Berriro saiatzeko, joan Ezarpenak atalera."</string> <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea"</string> <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Aurpegi bidez desblokeatzea"</string> <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Konfiguratu aurpegi bidez desblokeatzeko eginbidea"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelitea, konexio ona"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelitea, konexioa erabilgarri"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelite bidezko SOS komunikazioa"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Larrialdi-deiak edo SOS komunikazioa"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ez dago seinalerik"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"barra bat"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Erabili hatz-marka irekitzeko"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentifikazioa behar da. Autentifikatzeko, ukitu hatz-marken sentsorea."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Deia abian"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datu-konexioa"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Konektatuta"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Aldi baterako konektatuta"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Oraingo aplikazioa"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Lasterbideak"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pertsonalizatu lasterbideak"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Pertsonalizatu lasterbideak"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Lasterbidea kendu nahi duzu?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Balio lehenetsia berrezarri nahi duzu?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Sakatu tekla lasterbidea esleitzeko"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tekla-konbinazio hori erabili da dagoeneko. Probatu beste tekla bat."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Ezin da ezarri lasterbidea."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Gehitu lasterbide bat"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Ezabatu lasterbidea"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nabigatu teklatua erabilita"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ikasi lasterbideak"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nabigatu ukipen-panela erabilita"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index ae15b2ffe203..2caaf1415470 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ماهواره، اتصال خوب است"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ماهواره، اتصال دردسترس است"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"درخواست کمک ماهوارهای"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"تماس اضطراری یا درخواست کمک اضطراری"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>، <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"سیگنال وجود ندارد"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"یک خط"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"وارد شدن به دستگاه"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"از اثر انگشت برای باز کردن قفل استفاده کنید"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"اصالتسنجی لازم است. برای اصالتسنجی، حسگر اثر انگشت را لمس کنید."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"تماس درحال انجام"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"داده تلفن همراه"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"متصل است"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"موقتاً متصل است"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"برنامه فعلی"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترسپذیری"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"میانبرهای صفحهکلید"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"سفارشیسازی کردن میانبرهای صفحهکلید"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"سفارشیسازی میانبرها"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"میانبر حذف شود؟"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"به تنظیم پیشفرض بازنشانی میکنید؟"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"برای اختصاص دادن میانبر، کلید را فشار دهید"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ترکیب کلید ازقبل درحال استفاده است. کلید دیگری را امتحان کنید."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"میانبر تنظیم نشد."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"افزودن میانبر"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"حذف میانبر"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"پیمایش کردن بااستفاده از صفحهکلید"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"آشنایی با میانبرهای صفحهکلید"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"پیمایش کردن بااستفاده از صفحه لمسی"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 3220bfcb8d65..0bd79100a959 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -761,7 +761,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliitti, hyvä yhteys"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliitti, yhteys saatavilla"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hätäpuhelut tai Satellite SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ei signaalia"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"yksi palkki"</string> @@ -1291,8 +1292,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"avataksesi laitteen"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Avaa sormenjäljellä"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Todennus vaaditaan. Todenna koskettamalla sormenjälkitunnistinta."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Käynnissä oleva puhelu"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiilidata"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Yhdistetty"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Väliaikaisesti yhdistetty"</string> @@ -1439,7 +1439,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Nykyinen sovellus"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Pikanäppäimet"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Pikanäppäimien muokkaaminen"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Muokkaa pikanäppäimiä"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Poistetaanko pikanäppäin?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Palautetaanko oletusasetukset?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Määritä pikanäppäin painamalla näppäintä"</string> @@ -1467,6 +1467,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Näppäinyhdistelmä on jo käytössä. Kokeile toista näppäintä."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Pikakuvaketta ei voi lisätä."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Lisää pikanäppäin"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Poista pikanäppäin"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Siirry käyttämällä näppäimistöä"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Opettele pikanäppäimiä"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Siirry käyttämällä kosketuslevyä"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 367c7591a2b7..f93ceb498f4c 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite accessible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS par satellite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Appels d\'urgence ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"aucun signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"une barre"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Servez-vous de votre empreinte digitale pour ouvrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentification requise. Touchez le capteur d\'empreintes digitales pour vous authentifier."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Appel en cours"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Données cellulaires"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connexion active"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connectée temporairement"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis-clavier"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis-clavier"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personnaliser les raccourcis"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Supprimer le raccourci?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Réinitialiser aux raccourcis par défaut?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Appuyez sur la touche pour attribuer un raccourci"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"La combinaison de touches est déjà utilisée. Essayez une autre touche."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Le raccourci ne peut pas être défini."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Ajouter un raccourci"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Supprimer le raccourci"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide de votre clavier"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis-clavier"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index dc10bcbf74be..f0cc3b52fa02 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Bonne connexion satellite"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Connexion satellite disponible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS par satellite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Appels d\'urgence ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"aucun signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"faible"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilisez votre empreinte pour ouvrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Authentification requise. Appuyez sur le lecteur d\'empreintes digitales pour vous authentifier."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Appel en cours"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Données mobiles"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connecté"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connexion temporaire"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Appli actuelle"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Raccourcis clavier"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personnaliser les raccourcis clavier"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personnaliser les raccourcis"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Supprimer le raccourci ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Rétablir les paramètres par défaut ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Appuyez sur une touche pour attribuer un raccourci"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinaison de touches déjà utilisée. Essayez une autre touche."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Impossible de définir le raccourci."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Ajouter un raccourci"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Supprimer le raccourci"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviguer à l\'aide du clavier"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Apprenez à utiliser les raccourcis clavier"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviguer à l\'aide de votre pavé tactile"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index eef9147bbfab..a449530050e5 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa conexión"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexión dispoñible"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS por satélite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emerxencia ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"non hai cobertura"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"unha barra"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"poñer o dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa a impresión dixital para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Requírese autenticación. Para autenticarte, toca o sensor de impresión dixital."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada en curso"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Datos móbiles"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectada"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectada temporalmente"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicación actual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Atallos de teclado"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar os atallos de teclado"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar os atallos"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Queres quitar o atallo?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Queres restablecer a opción predeterminada?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Preme a tecla para asignar o atallo"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Xa se está usando esta combinación de teclas. Proba con outra."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Non se puido definir o atallo."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Engadir un atallo"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Eliminar un atallo"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navega co teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprende a usar os atallos de teclado"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navega co panel táctil"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 88b4f34c90c3..727d11248e8c 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"સૅટલાઇટ, સારું કનેક્શન"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"સૅટલાઇટ, કનેક્શન ઉપલબ્ધ છે"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ઇમર્જન્સી સૅટલાઇટ સહાય"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ઇમર્જન્સી કૉલ અથવા SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"કોઈ સિગ્નલ નથી"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"એક બાર"</string> @@ -843,7 +844,7 @@ <string name="keyboard_key_page_up" msgid="173914303254199845">"Page Up"</string> <string name="keyboard_key_page_down" msgid="9035902490071829731">"Page Down"</string> <string name="keyboard_key_forward_del" msgid="5325501825762733459">"Delete"</string> - <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc કી"</string> + <string name="keyboard_key_esc" msgid="6230365950511411322">"Esc"</string> <string name="keyboard_key_move_home" msgid="3496502501803911971">"Home"</string> <string name="keyboard_key_move_end" msgid="99190401463834854">"End"</string> <string name="keyboard_key_insert" msgid="4621692715704410493">"Insert"</string> @@ -881,7 +882,7 @@ <string name="group_system_cycle_back" msgid="8194102916946802902">"તાજેતરની ઍપ પર પાછળ જાઓ"</string> <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"ઍપની સૂચિ ખોલો"</string> <string name="group_system_access_system_settings" msgid="8731721963449070017">"સેટિંગ ખોલો"</string> - <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Assistant ખોલો"</string> + <string name="group_system_access_google_assistant" msgid="7210074957915968110">"આસિસ્ટંટ ખોલો"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"લૉક સ્ક્રીન"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"નોંધ લો"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"એકસાથે એકથી વધુ કાર્યો કરવા"</string> @@ -1069,7 +1070,7 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"સ્ક્રીન રેકોર્ડિંગ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"સ્ટૅન્ડબાય"</string> - <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ફૉન્ટનું કદ"</string> + <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ફૉન્ટ સાઇઝ"</string> <string name="font_scaling_smaller" msgid="1012032217622008232">"વધુ નાનું બનાવો"</string> <string name="font_scaling_larger" msgid="5476242157436806760">"વધુ મોટું બનાવો"</string> <string name="magnification_window_title" msgid="4863914360847258333">"વિસ્તૃતીકરણ વિંડો"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ખોલવા માટે ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"પ્રમાણીકરણ આવશ્યક છે. પ્રમાણિત કરવા માટે ફિંગરપ્રિન્ટ સેન્સરને ટચ કરો."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ચાલુ કૉલ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"મોબાઇલ ડેટા"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"કનેક્ટ કરેલું"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"હંગામી રીતે કનેક્ટ કર્યું"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"હાલની ઍપ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"કીબોર્ડ શૉર્ટકટ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"કીબોર્ડ શૉર્ટકટને કસ્ટમાઇઝ કરો"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"શૉર્ટકટ કસ્ટમાઇઝ કરો"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"શું શૉર્ટકટ કાઢી નાખીએ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"પાછા ડિફૉલ્ટ પર રીસેટ કરીએ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"શૉર્ટકટ સોંપવા માટે કી દબાવો"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"કી સંયોજન પહેલેલેથી ઉપયોગમાં છે. અન્ય કી અજમાવી જુઓ."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"શૉર્ટકટ સેટ કરી શકાતો નથી."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"શૉર્ટકટ ઉમેરો"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"શૉર્ટકટ ડિલીટ કરો"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"તમારા કીબોર્ડ વડે નૅવિગેટ કરો"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"કીબોર્ડ શૉર્ટકર્ટ જાણો"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"તમારા ટચપૅડ વડે નૅવિગેટ કરો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 1f7066e0d663..f58512db0863 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सैटलाइट कनेक्शन अच्छा है"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सैटलाइट कनेक्शन उपलब्ध है"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"सैटलाइट एसओएस"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आपातकालीन कॉल या एसओएस"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"सिग्नल नहीं है"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"एक सिग्नल बार"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"खोलने के लिए, फ़िंगरप्रिंट का इस्तेमाल करें"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"पुष्टि करना ज़रूरी है. पुष्टि करने के लिए, फ़िंगरप्रिंट सेंसर को छुएं."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"पहले से जारी कॉल"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"कनेक्ट हो गया"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"इंटरनेट कनेक्शन कुछ समय के लिए है"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"मौजूदा ऐप्लिकेशन"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट को पसंद के मुताबिक बनाएं"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"पसंद के मुताबिक शॉर्टकट बनाएं"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"क्या आपको शॉर्टकट हटाना है?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"क्या आपको फिर से डिफ़ॉल्ट सेटिंग चालू करनी है?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"शॉर्टकट असाइन करने के लिए बटन दबाएं"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"बटन का यह कॉम्बिनेशन पहले से इस्तेमाल किया जा रहा है. कोई दूसरा कॉम्बिनेशन आज़माएं."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"शॉर्टकट सेट नहीं किया जा सकता."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"शॉर्टकट जोड़ें"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"शॉर्टकट मिटाएं"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"कीबोर्ड का इस्तेमाल करके नेविगेट करें"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट के बारे में जानें"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचपैड का इस्तेमाल करके नेविगेट करें"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 5c40a5170fa7..b8b5f82dbf71 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra veza"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, veza je dostupna"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS putem satelita"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Hitni pozivi ili SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nema signala"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"jedna crtica"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"pristupili uređaju"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorite pomoću otiska prsta"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Potrebna je autentifikacija. Dodirnite senzor otiska prsta da biste se autentificirali."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Poziv u tijeku"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilni podaci"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Privremeno povezano"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutačna aplikacija"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tipkovni prečaci"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagodba tipkovnih prečaca"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Prilagodite prečace"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite li ukloniti prečac?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite li vratiti na zadano?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipku da biste dodijelili prečac"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ta se kombinacija već koristi. Pokušajte s nekom drugom."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Prečac se ne može postaviti."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Dodaj prečac"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Izbriši prečac"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krećite se pomoću tipkovnice"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Saznajte više o tipkovnim prečacima"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krećite se pomoću dodirne podloge"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 50c60833574a..e914e755a934 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Műhold, jó kapcsolat"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Műhold, van rendelkezésre álló kapcsolat"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Műholdas SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Segélyhívás vagy SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nincs jel"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"egy sáv"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"eszköz megadásához"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ujjlenyomat használata a megnyitáshoz"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Hitelesítés szükséges. Érintse meg az ujjlenyomat-érzékelőt a hitelesítéshez."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Hívás folyamatban"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiladat"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Csatlakozva"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ideiglenesen csatlakoztatva"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Jelenlegi alkalmazás"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Billentyűparancsok"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"A billentyűparancsok személyre szabása"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Gyorsparancsok személyre szabása"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Eltávolítja a billentyűparancsot?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Visszaállítja az alapértelmezett beállításokat?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Nyomja meg a billentyűt a billentyűparancs hozzárendeléséhez"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"A billentyűkombináció már használatban van. Próbálkozzon másik billentyűvel."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Nem lehet beállítani a billentyűparancsot."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Billentyűparancs hozzáadása"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Billentyűparancs törlése"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigáció a billentyűzet segítségével"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Billentyűparancsok megismerése"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigálás az érintőpaddal"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 2e42ecd6a25f..262c3dd93cdd 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Արբանյակային լավ կապ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Հասանելի է արբանյակային կապ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Շտապ կանչեր կամ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>։"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ազդանշան չկա"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"մեկ գիծ"</string> @@ -884,7 +885,7 @@ <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Բացել Օգնականը"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Կողպէկրան"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"Ստեղծել նշում"</string> - <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Բազմախնդրություն"</string> + <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Բազմախնդրություն"</string> <string name="system_multitasking_rhs" msgid="8779289852395243004">"Տրոհել էկրանը և տեղավորել այս հավելվածը աջ կողմում"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Տրոհել էկրանը և տեղավորել այս հավելվածը ձախ կողմում"</string> <string name="system_multitasking_full_screen" msgid="4940465971687159429">"Անցնել լիաէկրան ռեժիմի"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"նշել սարքը"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Բացելու համար օգտագործեք մատնահետքը"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Պահանջվում է նույնականացում։ Դրա համար մատը հպեք մատնահետքի սկաներին։"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ընթացիկ զանգ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Բջջային ինտերնետ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Միացած է"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ժամանակավոր կապ"</string> @@ -1430,14 +1430,14 @@ <string name="shortcut_helper_category_system" msgid="462110876978937359">"Համակարգ"</string> <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Համակարգի կառավարման տարրեր"</string> <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string> - <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string> + <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string> <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ներածում"</string> <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Հավելվածի դյուրանցումներ"</string> <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Այս հավելվածը"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Ստեղնային դյուրանցումներ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Կարգավորեք ստեղնային դյուրանցումներ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Դյուրանցումների անհատականացում"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Հեռացնե՞լ դյուրանցումը"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Վերականգնե՞լ կանխադրվածները"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Սեղմեք որևէ ստեղն՝ դյուրանցում նշանակելու համար"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ստեղների համակցությունն արդեն օգտագործվում է։ Ընտրեք ուրիշը։"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Դյուրանցումը հնարավոր չէ ստեղծել։"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Ավելացնել դյուրանցում"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Ջնջել դյուրանցումը"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Կողմնորոշվեք ձեր ստեղնաշարի օգնությամբ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Սովորեք օգտագործել ստեղնային դյուրանցումները"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Կողմնորոշվեք ձեր հպահարթակի օգնությամբ"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 2740ce508515..8e1118c76e24 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, koneksi baik"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, koneksi tersedia"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via Satelit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Panggilan darurat atau SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"tidak ada sinyal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"satu batang"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"masukkan perangkat"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan sidik jari untuk membuka"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Perlu autentikasi. Sentuh sensor sidik jari untuk melakukan autentikasi."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Panggilan sedang berlangsung"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data seluler"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Terhubung"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Terhubung sementara"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikasi Saat Ini"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan keyboard"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan keyboard"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Sesuaikan pintasan"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Hapus pintasan?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Reset kembali ke pintasan default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tekan tombol untuk menetapkan pintasan"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinasi tombol sudah digunakan. Coba tombol lain."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Pintasan tidak dapat disetel."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Tambahkan pintasan"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Hapus pintasan"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Menggunakan keyboard untuk navigasi"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Pelajari pintasan keyboard"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Menavigasi menggunakan touchpad"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index a6de1d70805e..f5488e0939de 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Gervihnöttur, góð tenging"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Gervihnöttur, tenging tiltæk"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Gervihnattar-SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Neyðarsímtöl eða SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ekkert samband"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"eitt strik"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"opna tæki"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Opna með fingrafari"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Auðkenningar krafist. Auðkenndu með því að snerta fingrafaralesarann."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Símtal í gangi"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Farsímagögn"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Tengt"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tímabundin tenging"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Núverandi forrit"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Flýtilyklar"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sérsníddu flýtilykla"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Sérsníða flýtilykla"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Fjarlægja flýtileið?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Endurstilla á sjálfgefið?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ýttu á lykil til að stilla flýtileið"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Lyklasamsetningin er þegar í notkun. Prófaðu annan lykil."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Ekki er hægt að stilla flýtileið."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Bæta flýtileið við"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Eyða flýtileið"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Flettu með því að nota lyklaborðið"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Kynntu þér flýtilykla"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Flettu með því að nota snertiflötinn"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 86aeae467b91..81367f369159 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitare, connessione buona"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitare, connessione disponibile"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS satellitare"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chiamate di emergenza o SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nessun segnale"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"una barra"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"accedere al dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Usa l\'impronta per aprire"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticazione obbligatoria. Eseguila toccando il sensore di impronte digitali."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chiamata in corso"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dati mobili"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Connessa"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Connessa temporaneamente"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App corrente"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Scorciatoie da tastiera"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizza scorciatoie da tastiera"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizza scorciatoie"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Rimuovere scorciatoia?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vuoi ripristinare le impostazioni predefinite?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Premi un tasto per assegnare una scorciatoia"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinazione di tasti già in uso. Prova con un altro tasto."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Impossibile impostare la scorciatoia."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Aggiungi scorciatoia"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Elimina scorciatoia"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviga usando la tastiera"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Informazioni sulle scorciatoie da tastiera"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviga usando il touchpad"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 605a1fb88cc3..a40dd62c4620 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -129,7 +129,7 @@ <string name="screenrecord_stop_label" msgid="72699670052087989">"עצירה"</string> <string name="screenrecord_share_label" msgid="5025590804030086930">"שיתוף"</string> <string name="screenrecord_save_title" msgid="1886652605520893850">"הקלטת המסך נשמרה"</string> - <string name="screenrecord_save_text" msgid="3008973099800840163">"יש להקיש כדי להציג"</string> + <string name="screenrecord_save_text" msgid="3008973099800840163">"יש ללחוץ כדי להציג"</string> <string name="screenrecord_save_error" msgid="5862648532560118815">"שגיאה בשמירה של הקלטת המסך"</string> <string name="screenrecord_start_error" msgid="2200660692479682368">"שגיאה בהפעלה של הקלטת המסך"</string> <string name="screenrecord_stop_dialog_title" msgid="8716193661764511095">"לעצור את ההקלטה?"</string> @@ -162,7 +162,7 @@ <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"הבעיה בתהליך הקלטה"</string> <string name="issuerecord_share_label" msgid="3992657993619876199">"שיתוף"</string> <string name="issuerecord_save_title" msgid="4161043023696751591">"הקלטת הבעיה נשמרה"</string> - <string name="issuerecord_save_text" msgid="1205985304551521495">"אפשר להקיש כדי להציג"</string> + <string name="issuerecord_save_text" msgid="1205985304551521495">"אפשר ללחוץ כדי להציג"</string> <string name="issuerecord_save_error" msgid="6913040083446722726">"שגיאה בשמירה של בעיית ההקלטה"</string> <string name="issuerecord_start_error" msgid="3402782952722871190">"שגיאה בהפעלה של בעיית ההקלטה"</string> <string name="immersive_cling_title" msgid="8372056499315585941">"צפייה במסך מלא"</string> @@ -187,17 +187,17 @@ <string name="biometric_dialog_logo" msgid="7681107853070774595">"לוגו של האפליקציה"</string> <string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string> <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string> - <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"יש להקיש כדי לבטל את האימות"</string> + <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"יש ללחוץ כדי לבטל את האימות"</string> <string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"יש לנסות שוב"</string> <string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"המערכת מחפשת את הפנים שלך"</string> <string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"זיהוי הפנים בוצע"</string> <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" 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_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string> <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string> - <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להקיש כדי להמשיך."</string> + <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך ללחוץ כדי להמשיך."</string> <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string> <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ביטול האימות"</string> <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"אפשרויות נוספות"</string> @@ -300,7 +300,7 @@ <string name="quick_settings_modes_label" msgid="879156359479504244">"מצבים"</string> <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string> <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"אין מכשירים מותאמים זמינים"</string> - <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"אפשר להקיש כדי להתחבר למכשיר או להתנתק ממנו"</string> + <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> @@ -449,7 +449,7 @@ <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"המצלמה כבויה"</string> <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"הגישה למצלמה הופעלה לכל האפליקציות והשירותים."</string> <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"הגישה למצלמה הושבתה לכל האפליקציות והשירותים."</string> - <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"כדי להשתמש בלחצן המיקרופון יש להפעיל את הגישה למיקרופון ב\'הגדרות\'."</string> + <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"כדי להשתמש בכפתור המיקרופון יש להפעיל את הגישה למיקרופון ב\'הגדרות\'."</string> <string name="sensor_privacy_dialog_open_settings" msgid="5635865896053011859">"פתיחת ההגדרות"</string> <string name="media_seamless_other_device" msgid="4654849800789196737">"מכשיר אחר"</string> <string name="quick_step_accessibility_toggle_overview" msgid="7908949976727578403">"החלפת מצב של מסכים אחרונים"</string> @@ -467,8 +467,8 @@ <string name="zen_priority_customize_button" msgid="4119213187257195047">"התאמה אישית"</string> <string name="zen_silence_introduction_voice" msgid="853573681302712348">"הפעולה הזו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. עדיין ניתן לבצע שיחות."</string> <string name="zen_silence_introduction" msgid="6117517737057344014">"הפעולה הזו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string> - <string name="notification_tap_again" msgid="4477318164947497249">"יש להקיש שוב כדי לפתוח את ההתראה"</string> - <string name="tap_again" msgid="1315420114387908655">"צריך להקיש פעם נוספת"</string> + <string name="notification_tap_again" msgid="4477318164947497249">"יש ללחוץ שוב כדי לפתוח את ההתראה"</string> + <string name="tap_again" msgid="1315420114387908655">"צריך ללחוץ פעם נוספת"</string> <string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string> <string name="keyguard_unlock_press" msgid="9140109453735019209">"לפתיחה, לוחצים על סמל ביטול הנעילה"</string> <string name="keyguard_face_successful_unlock_swipe" msgid="6180997591385846073">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להחליק כדי לפתוח."</string> @@ -538,7 +538,7 @@ <string name="glanceable_hub_lockscreen_affordance_label" msgid="1461611028615752141">"ווידג\'טים"</string> <string name="glanceable_hub_lockscreen_affordance_disabled_text" msgid="599170482297578735">"כדי להוסיף את קיצור הדרך \"ווידג\'טים\", צריך לוודא שהאפשרות \"ווידג\'טים במסך הנעילה\" מופעלת בהגדרות."</string> <string name="glanceable_hub_lockscreen_affordance_action_button_label" msgid="7636151133344609375">"הגדרות"</string> - <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"לחצן להצגת שומר המסך"</string> + <string name="accessibility_glanceable_hub_to_dream_button" msgid="7552776300297055307">"כפתור להצגת שומר המסך"</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> @@ -677,8 +677,8 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'דף הבית\' כדי לבטל את ההצמדה."</string> <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"ייתכן שתתאפשר גישה למידע אישי (כמו אנשי קשר ותוכן מהאימייל)."</string> <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"האפליקציה שהוצמדה עשויה לפתוח אפליקציות אחרות."</string> - <string name="screen_pinning_toast" msgid="8177286912533744328">"כדי לבטל את ההצמדה של האפליקציה הזו, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\'"</string> - <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"כדי לבטל את ההצמדה של האפליקציה הזו, יש ללחוץ לחיצה ארוכה על הלחצן \'הקודם\' והלחצן הראשי"</string> + <string name="screen_pinning_toast" msgid="8177286912533744328">"כדי לבטל את ההצמדה של האפליקציה הזו, יש ללחוץ לחיצה ארוכה על הכפתורים \"הקודם\" ו\"סקירה\""</string> + <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"כדי לבטל את ההצמדה של האפליקציה הזו, יש ללחוץ לחיצה ארוכה על הכפתור \"הקודם\" והכפתור הראשי"</string> <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"לביטול ההצמדה של האפליקציה הזו, יש להחליק למעלה ולהחזיק"</string> <string name="screen_pinning_positive" msgid="3285785989665266984">"הבנתי"</string> <string name="screen_pinning_negative" msgid="6882816864569211666">"לא, תודה"</string> @@ -702,19 +702,19 @@ <string name="stream_media_unavailable" msgid="6823020894438959853">"לא זמין כי התכונה \'נא לא להפריע\' מופעלת"</string> <string name="stream_unavailable_by_modes" msgid="3674139029490353683">"לא זמין כי המצב <xliff:g id="MODE">%s</xliff:g> מופעל"</string> <string name="stream_unavailable_by_unknown" msgid="6908434629318171588">"לא זמין"</string> - <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. יש להקיש כדי לבטל את ההשתקה."</string> - <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. צריך להקיש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string> - <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. יש להקיש כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string> - <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. יש להקיש כדי להעביר למצב רטט."</string> - <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. יש להקיש כדי להשתיק."</string> + <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. יש ללחוץ כדי לבטל את ההשתקה."</string> + <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. צריך ללחוץ כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string> + <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. יש ללחוץ כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string> + <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. יש ללחוץ כדי להעביר למצב רטט."</string> + <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. יש ללחוץ כדי להשתיק."</string> <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"בקרת רעש"</string> <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_ringer_change" msgid="3574969197796055532">"יש להקיש כדי לשנות את מצב תוכנת הצלצול"</string> + <string name="volume_ringer_change" msgid="3574969197796055532">"יש ללחוץ כדי לשנות את מצב תוכנת הצלצול"</string> <string name="volume_ringer_mode" msgid="6867838048430807128">"מצב תוכנת הצלצול"</string> - <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, צריך להקיש כדי לשנות את מצב תוכנת הצלצול"</string> + <string name="volume_ringer_drawer_closed_content_description" msgid="4737792429808781745">"<xliff:g id="VOLUME_RINGER_STATUS">%1$s</xliff:g>, צריך ללחוץ כדי לשנות את מצב תוכנת הצלצול"</string> <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"השתקה"</string> <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ביטול ההשתקה"</string> <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"רטט"</string> @@ -736,12 +736,12 @@ <string name="enable_demo_mode" msgid="3180345364745966431">"הפעלת מצב הדגמה"</string> <string name="show_demo_mode" msgid="3677956462273059726">"הצגת מצב הדגמה"</string> <string name="status_bar_ethernet" msgid="5690979758988647484">"אתרנט"</string> - <string name="status_bar_alarm" msgid="87160847643623352">"התראה"</string> + <string name="status_bar_alarm" msgid="87160847643623352">"שעון מעורר"</string> <string name="active_mode_content_description" msgid="1627555562186515927">"מצב <xliff:g id="MODENAME">%1$s</xliff:g> פועל"</string> <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string> <string name="wallet_empty_state_label" msgid="7776761245237530394">"מגדירים אמצעי תשלום ונהנים מביצוע מהיר ומאובטח יותר של רכישות באמצעות הטלפון"</string> <string name="wallet_app_button_label" msgid="7123784239111190992">"הצגת הכול"</string> - <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"יש להקיש לפתיחה"</string> + <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"יש ללחוץ לפתיחה"</string> <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"מתבצע עדכון"</string> <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"יש לבטל את הנעילה כדי להשתמש"</string> <string name="wallet_error_generic" msgid="257704570182963611">"הייתה בעיה בקבלת הכרטיסים שלך. כדאי לנסות שוב מאוחר יותר"</string> @@ -750,7 +750,7 @@ <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"מתבצע עדכון"</string> <string name="status_bar_work" msgid="5238641949837091056">"פרופיל עבודה"</string> <string name="status_bar_airplane" msgid="4848702508684541009">"מצב טיסה"</string> - <string name="zen_alarm_warning" msgid="7844303238486849503">"לא ניתן יהיה לשמוע את ההתראה הבאה שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string> + <string name="zen_alarm_warning" msgid="7844303238486849503">"לא ניתן יהיה לשמוע את השעון המעורר הבא שלך <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template" msgid="2234991538018805736">"בשעה <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="3561752195856839456">"ב-<xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"נקודת אינטרנט (hotspot)"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"לוויין, חיבור באיכות טובה"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"לוויין, יש חיבור זמין"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"תקשורת לוויינית למצב חירום"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"שיחות חירום או SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"אין קליטה"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"פס אחד"</string> @@ -827,7 +828,7 @@ <string name="snoozeHourOptions" msgid="2332819756222425558">"{count,plural, =1{שעה}=2{שעתיים}one{# שעות}other{# שעות}}"</string> <string name="snoozeMinuteOptions" msgid="2222082405822030979">"{count,plural, =1{דקה}one{# דקות}two{# דקות}other{# דקות}}"</string> <string name="battery_detail_switch_title" msgid="6940976502957380405">"חיסכון בסוללה"</string> - <string name="keyboard_key_button_template" msgid="8005673627272051429">"לחצן <xliff:g id="NAME">%1$s</xliff:g>"</string> + <string name="keyboard_key_button_template" msgid="8005673627272051429">"כפתור <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="keyboard_key_home" msgid="3734400625170020657">"דף הבית"</string> <string name="keyboard_key_back" msgid="4185420465469481999">"הקודם"</string> <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string> @@ -871,9 +872,9 @@ <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"מוצגים: קיצורי הדרך של הקלט"</string> <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"מוצגים: קיצורי הדרך לפתיחת אפליקציות"</string> <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"מוצגים: קיצורי הדרך של האפליקציה הנוכחית"</string> - <string name="group_system_access_notification_shade" msgid="1619028907006553677">"הצגת התראות"</string> + <string name="group_system_access_notification_shade" msgid="1619028907006553677">"צפייה בהתראות"</string> <string name="group_system_full_screenshot" msgid="5742204844232667785">"צילום המסך"</string> - <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"הצגת מקשי הקיצור"</string> + <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"צפייה במקשי הקיצור"</string> <string name="group_system_go_back" msgid="2730322046244918816">"חזרה"</string> <string name="group_system_access_home_screen" msgid="4130366993484706483">"מעבר למסך הבית"</string> <string name="group_system_overview_open_apps" msgid="5659958952937994104">"צפייה באפליקציות האחרונות"</string> @@ -912,7 +913,7 @@ <string name="keyboard_shortcut_group_applications_calculator" msgid="6316043911946540137">"מחשבון"</string> <string name="keyboard_shortcut_group_applications_maps" msgid="7312554713993114342">"מפות"</string> <string name="volume_and_do_not_disturb" msgid="502044092739382832">"נא לא להפריע"</string> - <string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך ללחצני עוצמת קול"</string> + <string name="volume_dnd_silent" msgid="4154597281458298093">"קיצור דרך לכפתורי עוצמת קול"</string> <string name="battery" msgid="769686279459897127">"סוללה"</string> <string name="headset" msgid="4485892374984466437">"אוזניות"</string> <string name="accessibility_long_click_tile" msgid="210472753156768705">"פתיחת ההגדרות"</string> @@ -926,8 +927,8 @@ <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"מידע נוסף"</string> <string name="nav_bar" msgid="4642708685386136807">"סרגל הניווט"</string> <string name="nav_bar_layout" msgid="4716392484772899544">"פריסה"</string> - <string name="left_nav_bar_button_type" msgid="2634852842345192790">"סוג נוסף של לחצן שמאלי"</string> - <string name="right_nav_bar_button_type" msgid="4472566498647364715">"סוג נוסף של לחצן ימני"</string> + <string name="left_nav_bar_button_type" msgid="2634852842345192790">"סוג נוסף של כפתור שמאלי"</string> + <string name="right_nav_bar_button_type" msgid="4472566498647364715">"סוג נוסף של כפתור ימני"</string> <string-array name="nav_bar_buttons"> <item msgid="2681220472659720036">"לוח"</item> <item msgid="4795049793625565683">"קוד מפתח"</item> @@ -943,7 +944,7 @@ <string name="save" msgid="3392754183673848006">"שמירה"</string> <string name="reset" msgid="8715144064608810383">"איפוס"</string> <string name="clipboard" msgid="8517342737534284617">"לוח"</string> - <string name="accessibility_key" msgid="3471162841552818281">"לחצן לניווט מותאם אישית"</string> + <string name="accessibility_key" msgid="3471162841552818281">"כפתור לניווט מותאם אישית"</string> <string name="left_keycode" msgid="8211040899126637342">"קוד מפתח שמאלי"</string> <string name="right_keycode" msgid="2480715509844798438">"קוד מפתח ימני"</string> <string name="left_icon" msgid="5036278531966897006">"סמל שמאלי"</string> @@ -1020,7 +1021,7 @@ <string name="instant_apps" msgid="8337185853050247304">"אפליקציות ללא התקנה"</string> <string name="instant_apps_title" msgid="8942706782103036910">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת"</string> <string name="instant_apps_message" msgid="6112428971833011754">"האפליקציה נפתחת בלי התקנה."</string> - <string name="instant_apps_message_with_help" msgid="1816952263531203932">"האפליקציה נפתחת בלי התקנה. אפשר להקיש כדי לקבל מידע נוסף."</string> + <string name="instant_apps_message_with_help" msgid="1816952263531203932">"האפליקציה נפתחת בלי התקנה. אפשר ללחוץ כדי לקבל מידע נוסף."</string> <string name="app_info" msgid="5153758994129963243">"פרטי האפליקציה"</string> <string name="go_to_web" msgid="636673528981366511">"מעבר אל הדפדפן"</string> <string name="mobile_data" msgid="4564407557775397216">"חבילת גלישה"</string> @@ -1034,7 +1035,7 @@ <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה (<xliff:g id="ID_1">%s</xliff:g>)."</string> <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"מצב \'נא לא להפריע\' הופעל על ידי אפליקציה או על ידי כלל אוטומטי."</string> <string name="running_foreground_services_title" msgid="5137313173431186685">"אפליקציות שפועלות ברקע"</string> - <string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר להקיש לקבלת פרטים על צריכה של נתונים וסוללה"</string> + <string name="running_foreground_services_msg" msgid="3009459259222695385">"אפשר ללחוץ לקבלת פרטים על צריכה של נתונים וסוללה"</string> <string name="mobile_data_disable_title" msgid="5366476131671617790">"לכבות את השימוש בחבילת הגלישה?"</string> <string name="mobile_data_disable_message" msgid="8604966027899770415">"לא תהיה לך גישה לנתונים או לאינטרנט דרך <xliff:g id="CARRIER">%s</xliff:g>. אפשר יהיה לגשת לאינטרנט רק דרך Wi-Fi."</string> <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"הספק שלך"</string> @@ -1049,7 +1050,7 @@ <string name="slice_permission_checkbox" msgid="4242888137592298523">"יש לאשר לאפליקציית <xliff:g id="APP">%1$s</xliff:g> להראות חלקים מכל אפליציה שהיא"</string> <string name="slice_permission_allow" msgid="6340449521277951123">"אישור"</string> <string name="slice_permission_deny" msgid="6870256451658176895">"אני לא מרשה"</string> - <string name="auto_saver_title" msgid="6873691178754086596">"יש להקיש כדי לתזמן את מצב החיסכון בסוללה"</string> + <string name="auto_saver_title" msgid="6873691178754086596">"יש ללחוץ כדי לתזמן את מצב החיסכון בסוללה"</string> <string name="auto_saver_text" msgid="3214960308353838764">"מומלץ להפעיל את התכונה כשיש סבירות גבוהה שהסוללה תתרוקן"</string> <string name="no_auto_saver_action" msgid="7467924389609773835">"לא תודה"</string> <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"בשימוש"</string> @@ -1109,11 +1110,11 @@ <string name="accessibility_magnification_done" msgid="263349129937348512">"סיום"</string> <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"עריכה"</string> <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"ההגדרות של חלון ההגדלה"</string> - <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"מקישים כדי לפתוח את תכונות הנגישות. אפשר להחליף את הלחצן או להתאים אותו אישית בהגדרות.\n\n"<annotation id="link">"הצגת ההגדרות"</annotation></string> - <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"כדי להסתיר זמנית את הלחצן, יש להזיז אותו לקצה"</string> + <string name="accessibility_floating_button_migration_tooltip" msgid="5217151214439341902">"לוחצים כדי לפתוח את תכונות הנגישות. אפשר להחליף את הכפתור או להתאים אותו אישית בהגדרות.\n\n"<annotation id="link">"הצגת ההגדרות"</annotation></string> + <string name="accessibility_floating_button_docking_tooltip" msgid="6814897496767461517">"כדי להסתיר זמנית את הכפתור, יש להזיז אותו לקצה"</string> <string name="accessibility_floating_button_undo" msgid="511112888715708241">"ביטול"</string> - <string name="accessibility_floating_button_hidden_notification_title" msgid="4115036997406994799">"לחצן הנגישות מוסתר"</string> - <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"אפשר להקיש כדי לראות את לחצן הנגישות"</string> + <string name="accessibility_floating_button_hidden_notification_title" msgid="4115036997406994799">"כפתור הנגישות מוסתר"</string> + <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"אפשר ללחוץ כדי לראות את כפתור הנגישות"</string> <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"קיצור הדרך אל <xliff:g id="FEATURE_NAME">%s</xliff:g> הוסר"</string> <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{קיצור הדרך הוסר}one{# קיצורי דרך הוסרו}two{# קיצורי דרך הוסרו}other{# קיצורי דרך הוסרו}}"</string> <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"העברה לפינה השמאלית העליונה"</string> @@ -1214,7 +1215,7 @@ <string name="media_output_dialog_single_device" msgid="3102758980643351058">"נבחר מכשיר אחד"</string> <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"נבחרו <xliff:g id="COUNT">%1$d</xliff:g> מכשירים"</string> <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(מנותק)"</string> - <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך להקיש כדי לנסות שוב."</string> + <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"לא ניתן להחליף. צריך ללחוץ כדי לנסות שוב."</string> <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"חיבור מכשיר"</string> <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string> <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"עצירת ההעברה (casting)"</string> @@ -1245,7 +1246,7 @@ <string name="copy_to_clipboard_a11y_action" msgid="4312789069718446749">"העתקה ללוח."</string> <string name="basic_status" msgid="2315371112182658176">"פתיחת שיחה"</string> <string name="select_conversation_title" msgid="6716364118095089519">"ווידג\'טים של שיחות"</string> - <string name="select_conversation_text" msgid="3376048251434956013">"יש להקיש על שיחה כדי להוסיף אותה למסך הבית"</string> + <string name="select_conversation_text" msgid="3376048251434956013">"יש ללחוץ על שיחה כדי להוסיף אותה למסך הבית"</string> <string name="no_conversations_text" msgid="5354115541282395015">"השיחות האחרונות שלך יופיעו כאן"</string> <string name="priority_conversations" msgid="3967482288896653039">"שיחות בעדיפות גבוהה"</string> <string name="recent_conversations" msgid="8531874684782574622">"שיחות אחרונות"</string> @@ -1280,17 +1281,16 @@ <string name="new_status_content_description" msgid="6046637888641308327">"הסטטוס של <xliff:g id="NAME">%1$s</xliff:g> עודכן: <xliff:g id="STATUS">%2$s</xliff:g>"</string> <string name="person_available" msgid="2318599327472755472">"אונליין"</string> <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string> - <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string> + <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש ללחוץ כדי להציג מידע נוסף"</string> <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה"</string> <string name="accessibility_bouncer" msgid="5896923685673320070">"הזנת קוד נעילת המסך"</string> - <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"צריך לגעת בחיישן טביעות האצבע. זה הלחצן הקצר יותר בצד של הטלפון"</string> + <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"צריך לגעת בחיישן טביעות האצבע. זה הכפתור הקצר יותר בצד של הטלפון"</string> <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"חיישן טביעות אצבע"</string> <string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string> <string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"שימוש בטביעת אצבע כדי לפתוח"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"נדרש אימות. יש לגעת בחיישן טביעות האצבע כדי לבצע אימות."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"שיחה פעילה"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"חבילת גלישה"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"מחובר"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"מחובר באופן זמני"</string> @@ -1300,7 +1300,7 @@ <string name="non_carrier_network_unavailable" msgid="770049357024492372">"אין רשתות זמינות אחרות"</string> <string name="all_network_unavailable" msgid="4112774339909373349">"אין רשתות זמינות"</string> <string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string> - <string name="tap_a_network_to_connect" msgid="1565073330852369558">"כדי להתחבר לרשת צריך להקיש עליה"</string> + <string name="tap_a_network_to_connect" msgid="1565073330852369558">"כדי להתחבר לרשת צריך ללחוץ עליה"</string> <string name="unlock_to_view_networks" msgid="5072880496312015676">"צריך לבטל את הנעילה כדי להציג את הרשתות"</string> <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"בתהליך חיפוש רשתות…"</string> <string name="wifi_failed_connect_message" msgid="4161863112079000071">"נכשל הניסיון להתחבר לרשת"</string> @@ -1326,7 +1326,7 @@ <string name="clipboard_edit_text_description" msgid="805254383912962103">"עריכת הטקסט שהועתק"</string> <string name="clipboard_edit_image_description" msgid="8904857948976041306">"עריכת התמונה שהועתקה"</string> <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"שליחה למכשיר בקרבת מקום"</string> - <string name="clipboard_text_hidden" msgid="7926899867471812305">"יש להקיש כדי להציג"</string> + <string name="clipboard_text_hidden" msgid="7926899867471812305">"יש ללחוץ כדי להציג"</string> <string name="clipboard_text_copied" msgid="5100836834278976679">"הטקסט הועתק"</string> <string name="clipboard_image_copied" msgid="3793365360174328722">"התמונה הועתקה"</string> <string name="clipboard_content_copied" msgid="144452398567828145">"התוכן הועתק"</string> @@ -1340,7 +1340,7 @@ <string name="dream_overlay_location_active" msgid="6484763493158166618">"המיקום פעיל"</string> <string name="dream_overlay_status_bar_wifi_off" msgid="4497069245055003582">"Wi‑Fi לא זמין"</string> <string name="dream_overlay_status_bar_priority_mode" msgid="5428462123314728739">"מצב עדיפות"</string> - <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"ההתראה מוגדרת"</string> + <string name="dream_overlay_status_bar_alarm_set" msgid="566707328356590886">"השעון המעורר מוגדר"</string> <string name="dream_overlay_status_bar_camera_off" msgid="5273073778969890823">"המצלמה כבויה"</string> <string name="dream_overlay_status_bar_mic_off" msgid="8366534415013819396">"המיקרופון כבוי"</string> <string name="dream_overlay_status_bar_camera_mic_off" msgid="3199425257833773569">"המצלמה והמיקרופון כבויים"</string> @@ -1433,17 +1433,18 @@ <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ריבוי משימות"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"מסך מפוצל"</string> <string name="shortcut_helper_category_input" msgid="8674018654124839566">"קלט"</string> - <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"קיצורי דרך של אפליקציות"</string> + <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"מקשי קיצור לאפליקציות"</string> <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"האפליקציה הנוכחית"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"מקשי קיצור"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"התאמה אישית של מקשי הקיצור"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"להסיר את קיצור הדרך?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"לאפס לברירת המחדל?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"צריך להקיש על מקש כדי להקצות מקש קיצור"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"קיצור הדרך יימחק לתמיד."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"הפעולה הזו תמחק לתמיד את כל קיצורי הדרך שמותאמים אישית."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"קיצורי דרך לחיפוש"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"חיפוש מקשי קיצור"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"אין תוצאות חיפוש"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"סמל הכיווץ"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"סמל מקש הפעולה (\"מטא\")"</string> @@ -1465,6 +1466,10 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"שילוב המקשים הזה כבר בשימוש. אפשר לנסות מקש אחר."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"לא ניתן להגדיר את קיצור הדרך."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <!-- no translation found for shortcut_helper_add_shortcut_button_label (7655779534665954910) --> + <skip /> + <!-- no translation found for shortcut_helper_delete_shortcut_button_label (3148773472696137052) --> + <skip /> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ניווט באמצעות המקלדת"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"מידע על מקשי קיצור"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ניווט באמצעות לוח המגע"</string> @@ -1510,13 +1515,13 @@ <string name="redacted_notification_single_line_text" msgid="8684166405005242945">"צריך לבטל את הנעילה כדי לראות"</string> <string name="contextual_education_dialog_title" msgid="4630392552837487324">"חינוך בהתאם להקשר"</string> <string name="back_edu_notification_title" msgid="5624780717751357278">"אפשר להשתמש בלוח המגע כדי לחזור אחורה"</string> - <string name="back_edu_notification_content" msgid="2497557451540954068">"מחליקים ימינה או שמאלה עם שלוש אצבעות. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string> + <string name="back_edu_notification_content" msgid="2497557451540954068">"מחליקים ימינה או שמאלה עם שלוש אצבעות. ניתן ללחוץ כדי לקבל מידע נוסף על התנועות."</string> <string name="home_edu_notification_title" msgid="6097902076909654045">"איך להשתמש בלוח המגע כדי לעבור למסך הבית"</string> - <string name="home_edu_notification_content" msgid="6631697734535766588">"מחליקים למעלה עם שלוש אצבעות. אפשר להקיש כדי לקבל מידע נוסף על התנועות."</string> + <string name="home_edu_notification_content" msgid="6631697734535766588">"מחליקים למעלה עם שלוש אצבעות. אפשר ללחוץ כדי לקבל מידע נוסף על התנועות."</string> <string name="overview_edu_notification_title" msgid="1265824157319562406">"איך להשתמש בלוח המגע כדי לראות את האפליקציות האחרונות"</string> - <string name="overview_edu_notification_content" msgid="3578204677648432500">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות. אפשר להקיש כדי לקבל מידע נוסף על התנועות."</string> + <string name="overview_edu_notification_content" msgid="3578204677648432500">"מחליקים למעלה ולוחצים לחיצה ארוכה עם שלוש אצבעות. אפשר ללחוץ כדי לקבל מידע נוסף על התנועות."</string> <string name="all_apps_edu_notification_title" msgid="372262997265569063">"איך להשתמש במקלדת כדי לראות את כל האפליקציות"</string> - <string name="all_apps_edu_notification_content" msgid="3255070575694025585">"בכל שלב אפשר ללחוץ על מקש הפעולה. ניתן להקיש כדי לקבל מידע נוסף על התנועות."</string> + <string name="all_apps_edu_notification_content" msgid="3255070575694025585">"בכל שלב אפשר ללחוץ על מקש הפעולה. ניתן ללחוץ כדי לקבל מידע נוסף על התנועות."</string> <string name="accessibility_deprecate_extra_dim_dialog_title" msgid="910988771011857460">"התכונה \'מעומעם במיוחד\' נוספה לפס ההזזה לבהירות"</string> <string name="accessibility_deprecate_extra_dim_dialog_description" msgid="4453123359258743230">"עכשיו אפשר להפוך את המסך למעומעם במיוחד באמצעות הפחתה נוספת של רמת הבהירות.\n\nהתכונה הזו היא עכשיו חלק מפס ההזזה לבהירות, לכן קיצורי הדרך לתכונה \'מעומעם במיוחד\' נמצאים בתהליך הסרה."</string> <string name="accessibility_deprecate_extra_dim_dialog_button" msgid="3947537827396916005">"הסרה של קיצורי הדרך לתכונה \'מעומעם במיוחד\'"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 4634a50c7199..8941217e8cbd 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛生、接続状態良好"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛生、接続利用可能"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"衛星 SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急通報または SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>、<xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>。"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"圏外"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"レベル 1"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"デバイスを入力"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"指紋を使って開いてください"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"認証が必要です。指紋認証センサーをタッチして認証してください。"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"モバイルデータ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"接続済み"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"一時的に接続されています"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"現在のアプリ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"キーボード ショートカット"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"キーボード ショートカットのカスタマイズ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ショートカットのカスタマイズ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ショートカットを削除しますか?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"デフォルトにリセットしますか?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ショートカットを割り当てるキーを押してください"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"このキーの組み合わせはすでに使用されています。別のキーを試してください。"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ショートカットを設定できません。"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ショートカットを追加"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ショートカットを削除"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"キーボードを使用して移動する"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"キーボード ショートカットの詳細"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"タッチパッドを使用して移動する"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index fc0b81dbcca5..6937048c1826 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"კარგი სატელიტური კავშირი"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ხელმისაწვდომია სატელიტური კავშირი"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"სატელიტური SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"გადაუდებელი ზარი ან SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"სიგნალი არ არის"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ერთი ხაზი"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"მოწყობილობის შეყვანა"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"გასახსნელად გამოიყენეთ თითის ანაბეჭდი"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"საჭიროა ავტორიზაცია. ავტორიზაციისთვის შეეხეთ თითის ანაბეჭდის სენსორს."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"მიმდინარე ზარი"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"მობილური ინტერნეტი"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"დაკავშირებული"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"დროებით დაკავშირებული"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"მიმდინარე აპი"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"კლავიატურის მალსახმობები"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"კლავიატურის მალსახმობების მორგება"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"მალსახმობების მორგება"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"გსურთ მალსახმობის წაშლა?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"გსურთ ნაგულისხმევზე გადაყენება?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"მალსახმობის მინიჭებისთვის დააჭირეთ კლავიშს"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"კლავიშების კომბინაცია უკვე გამოიყენება. ცადეთ სხვა კლავიში."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"მალსახმობის დაყენება ვერ ხერხდება."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"მალსახმობის დამატება"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"მალსახმობის წაშლა"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ნავიგაცია კლავიატურის გამოყენებით"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"კლავიატურის მალსახმობების სწავლა"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ნავიგაცია სენსორული პანელის გამოყენებით"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 643a1c27b675..d6f0a006f588 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Жерсерік, байланыс жақсы."</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Жерсерік, байланыс бар."</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Құтқару қызметіне қоңырау шалу немесе SOS сигналын жіберу"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"сигнал жоқ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"бір жолақ"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"құрылғыны енгізу"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ашу үшін саусақ ізін пайдаланыңыз."</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Аутентификациядан өту қажет. Ол үшін саусақ ізін оқу сканерін түртіңіз."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ағымдағы қоңырау"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобильдік интернет"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Жалғанды"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Уақытша байланыс орнатылды."</string> @@ -1437,13 +1437,13 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Қолданыстағы қолданба"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Перне тіркесімдері"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Пернелер тіркесімін бейімдеу"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Пернелер тіркесімін бейімдеу"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Тіркесімді өшіру керек пе?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Әдепкі тіркесімге қайтару керек пе?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Тіркесім тағайындау үшін пернені басыңыз."</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Арнаулы тіркесіміңіз біржола жойылады."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Мұндайда барлық арнаулы тіркесім біржола жойылады."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Іздеу жылдам пәрмендері"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Тіркесімдерді іздеу"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Іздеу нәтижелері жоқ."</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Жию белгішесі"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Әрекет немесе Meta пернесінің белгішесі"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Бұл пернелер тіркесімі қазір қолданыста. Басқа перне таңдаңыз."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Перне тіркесімін орнату мүмкін емес."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Жылдам пәрмен қосу"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Жылдам пәрменді жою"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Пернетақтамен жұмыс істеңіз"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Перне тіркесімдерін үйреніңіз."</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Сенсорлық тақтамен жұмыс істеңіз"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 239e2a9764a0..efbc0aa0d68c 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ផ្កាយរណប មានការតភ្ជាប់ល្អ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ផ្កាយរណប អាចតភ្ជាប់បាន"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ការប្រកាសអាសន្នតាមផ្កាយរណប"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ការហៅទៅលេខសង្គ្រោះបន្ទាន់ ឬ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>។"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"គ្មានសញ្ញា"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"មួយកាំ"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"បញ្ចូលឧបករណ៍"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ប្រើស្នាមម្រាមដៃ ដើម្បីបើក"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"តម្រូវឱ្យមានការផ្ទៀងផ្ទាត់។ សូមចុចឧបករណ៍ចាប់ស្នាមម្រាមដៃ ដើម្បីផ្ទៀងផ្ទាត់។"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ការហៅដែលកំពុងដំណើរការ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ទិន្នន័យទូរសព្ទចល័ត"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"បានភ្ជាប់"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"បានភ្ជាប់ជាបណ្ដោះអាសន្ន"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"កម្មវិធីបច្ចុប្បន្ន"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"ផ្លូវកាត់ក្ដារចុច"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ប្ដូរផ្លូវកាត់ក្ដារចុចតាមបំណង"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ប្ដូរផ្លូវកាត់តាមបំណង"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ដកផ្លូវកាត់ចេញឬ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"កំណត់ឡើងវិញទៅលំនាំដើមឬ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ចុចគ្រាប់ចុច ដើម្បីកំណត់ផ្លូវកាត់"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"បន្សំគ្រាប់ចុចនេះត្រូវបានប្រើប្រាស់ហើយ។ សាកល្បងគ្រាប់ចុចផ្សេង។"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"មិនអាចកំណត់ផ្លូវកាត់បានទេ។"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"បញ្ចូលផ្លូវកាត់"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"លុបផ្លូវកាត់"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"រុករកដោយប្រើក្ដារចុចរបស់អ្នក"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ស្វែងយល់អំពីផ្លូវកាត់ក្ដារចុច"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"រុករកដោយប្រើផ្ទាំងប៉ះរបស់អ្នក"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index 0b0caa4e51eb..ded267feee65 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಉತ್ತಮವಾಗಿದೆ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ಸ್ಯಾಟಲೈಟ್, ಕನೆಕ್ಷನ್ ಲಭ್ಯವಿದೆ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ಸ್ಯಾಟಲೈಟ್ SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ತುರ್ತು ಕರೆಗಳು ಅಥವಾ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ಸಿಗ್ನಲ್ ಇಲ್ಲ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ಒಂದು ಬಾರ್"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ತೆರೆಯುವುದಕ್ಕಾಗಿ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಬಳಸಿ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ದೃಢೀಕರಣದ ಅವಶ್ಯಕತೆಯಿದೆ. ದೃಢೀಕರಿಸಲು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ಮೊಬೈಲ್ ಡೇಟಾ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ತಾತ್ಕಾಲಿಕವಾಗಿ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ಪ್ರಸ್ತುತ ಆ್ಯಪ್"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಬೇಕೇ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ಡೀಫಾಲ್ಟ್ಗೆ ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ಕೀಯನ್ನು ಒತ್ತಿರಿ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ಕೀ ಸಂಯೋಜನೆಯು ಈಗಾಗಲೇ ಬಳಕೆಯಲ್ಲಿದೆ. ಮತ್ತೊಂದು ಕೀ ಬಳಸಿ ನೋಡಿ."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಸೆಟ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ಶಾರ್ಟ್ಕಟ್ ಸೇರಿಸಿ"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ಶಾರ್ಟ್ಕಟ್ ಅಳಿಸಿ"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ನಿಮ್ಮ ಕೀಬೋರ್ಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಕಲಿಯಿರಿ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ನಿಮ್ಮ ಟಚ್ಪ್ಯಾಡ್ ಬಳಸಿ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 14736604bcf8..732c9bc8620c 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"위성, 연결 상태 양호"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"위성, 연결 가능"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"위성 긴급 SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"긴급 전화 또는 SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"신호가 없습니다"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"신호 막대가 1개입니다"</string> @@ -882,7 +883,7 @@ <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"앱 목록 열기"</string> <string name="group_system_access_system_settings" msgid="8731721963449070017">"설정 열기"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"어시스턴트 열기"</string> - <string name="group_system_lock_screen" msgid="7391191300363416543">"잠금 화면"</string> + <string name="group_system_lock_screen" msgid="7391191300363416543">"화면 잠금"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"메모 작성"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"멀티태스킹"</string> <string name="system_multitasking_rhs" msgid="8779289852395243004">"앱이 오른쪽에 오도록 화면 분할 사용"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"기기 입력"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"지문으로 열기"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"인증이 필요합니다. 지문 센서를 터치하여 인증하세요."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"진행 중인 통화"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"모바일 데이터"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"연결됨"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"일시적으로 연결됨"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"현재 앱"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"단축키"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"단축키 맞춤설정"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"단축키 맞춤설정"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"단축키를 삭제하시겠어요?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"기본값으로 재설정하시겠어요?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"키를 눌러 단축키 지정"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"이미 사용 중인 키 조합입니다. 다른 키를 사용해 보세요."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"단축키를 설정할 수 없습니다."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"단축키 추가"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"단축키 삭제"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"키보드를 사용하여 이동"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"단축키에 관해 알아보세요."</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"터치패드를 사용하여 이동"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index ad70e7961dc6..eb5960fa23cd 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутник, байланыш жакшы"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Спутник, байланыш бар"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Спутник SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Шашылыш чалуулар же SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"сигнал жок"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"бир мамыча"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"түзмөккө кирүү"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Манжаңыздын изи менен ачыңыз"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Аныктыкты текшерүү талап кылынат. Аныктыгын текшерүү үчүн манжа изинин сенсоруна тийип коюңуз."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Учурдагы чалуу"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилдик трафик"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Туташты"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Убактылуу туташып турат"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Учурдагы колдонмо"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Ыкчам баскычтар"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Ыкчам баскычтарды ыңгайлаштыруу"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Ыкчам баскычтарды тууралоо"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ыкчам баскыч өчүрүлсүнбү?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Баштапкы абалга келтиресизби?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Ыкчам баскычты дайындоо үчүн баскычты басыңыз"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ачкычтардын айкалышы колдонулууда. Башка ачкычты байкап көрүңүз."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Ыкчам баскычты коюу мүмкүн эмес."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Ыкчам баскыч кошуу"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Ыкчам баскычты өчүрүү"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Керектүү нерселерге баскычтоп аркылуу өтүү"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ыкчам баскычтар тууралуу билип алыңыз"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Керектүү жерге сенсордук такта аркылуу өтөсүз"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 1c3d4110b793..19ddc7aa5c9a 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ດາວທຽມ, ການເຊື່ອມຕໍ່ດີ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ດາວທຽມ, ການເຊື່ອມຕໍ່ທີ່ພ້ອມນຳໃຊ້"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS ດາວທຽມ"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ໂທສຸກເສີນ ຫຼື SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ບໍ່ມີສັນຍານ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 ຂີດ"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ເຂົ້າອຸປະກອນ"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ໃຊ້ລາຍນິ້ວມືເພື່ອເປີດ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ຕ້ອງພິສູດຢືນຢັນ. ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມືເພື່ອພິສູດຢືນຢັນ."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ສາຍທີ່ສົນທະນາຢູ່"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ອິນເຕີເນັດມືຖື"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ເຊື່ອມຕໍ່ແລ້ວ"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ເຊື່ອມຕໍ່ແລ້ວຊົ່ວຄາວ"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ແອັບປັດຈຸບັນ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"ຄີລັດ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ປັບແຕ່ງຄີລັດ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ປັບແຕ່ງທາງລັດ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ລຶບທາງລັດອອກບໍ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ຣີເຊັດກັບຄືນເປັນຄ່າເລີ່ມຕົ້ນບໍ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ກົດປຸ່ມເພື່ອກຳນົດທາງລັດ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ນໍາໃຊ້ປຸ່ມປະສົມຢູ່ແລ້ວ. ໃຫ້ລອງປຸ່ມອື່ນ."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ຕັ້ງທາງລັດບໍ່ໄດ້."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ເພີ່ມທາງລັດ"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ລຶບທາງລັດ"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ນຳທາງໂດຍໃຊ້ແປ້ນພິມຂອງທ່ານ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ສຶກສາຄີລັດ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ນຳທາງໂດຍໃຊ້ແຜ່ນສຳຜັດຂອງທ່ານ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index eb6fd2d9eea7..71ce30db0a02 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Palydovas, geras ryšys"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Palydovas, pasiekiamas ryšys"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Prisijungimas prie palydovo kritiniu atveju"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Skambučiai pagalbos numeriu arba pagalbos iškvietimas kritiniu atveju"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"„<xliff:g id="CARRIER_NAME">%1$s</xliff:g>“, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nėra signalo"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"viena juosta"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"pasiektumėte įrenginį"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Naudokite kontrolinį kodą, kad atidarytumėte"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Reikia nustatyti tapatybę. Nustatykite tapatybę palietę kontrolinio kodo jutiklį."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Vykstantis skambutis"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiliojo ryšio duomenys"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Prisijungta"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Laikinai prijungta"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Esama programa"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Spartieji klavišai"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sparčiųjų klavišų tinkinimas"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Sparčiųjų klavišų tinkinimas"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Pašalinti spartųjį klavišą?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Iš naujo nustatyti numatytąjį nustatymą?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Paspauskite klavišą, kad priskirtumėte spartųjį klavišą"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Klavišų derinys jau naudojamas. Bandykite naudoti kitą klavišą."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Sparčiojo klavišo nustatyti negalima."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Pridėti spartųjį klavišą"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Ištrinti spartųjį klavišą"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naršykite naudodamiesi klaviatūra"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Sužinokite apie sparčiuosius klavišus"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naršykite naudodamiesi jutikline dalimi"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 7740d2d14c0f..271c081ea3a9 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelīts, labs savienojums"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelīts, ir pieejams savienojums"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelīta SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Ārkārtas izsaukumi vai ārkārtas zvani"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nav signāla"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"viena josla"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"izmantotu ierīci"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Atvēršanai izmantojiet pirksta nospiedumu"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Nepieciešama autentifikācija. Pieskarieties pirksta nospieduma sensoram, lai veiktu autentificēšanu."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Notiekošs zvans"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilie dati"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ir izveidots savienojums"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Īslaicīgi izveidots savienojums"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Pašreizējā lietotne"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Īsinājumtaustiņi"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Īsinājumtaustiņu pielāgošana"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Īsinājumtaustiņu pielāgošana"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vai noņemt saīsni?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vai atiestatīt noklusējuma vērtības?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Lai piešķirtu īsinājumtaustiņu, nospiediet taustiņu"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Taustiņu kombinācija jau tiek izmantota. Izmēģiniet citu taustiņu."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Nevar iestatīt saīsni."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Pievienot saīsni"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Dzēst saīsni"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pārvietošanās, izmantojot tastatūru"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Uzziniet par īsinājumtaustiņiem."</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pārvietošanās, izmantojot skārienpaliktni"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index e4064e239b34..b478a5b38c4b 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Добра сателитска врска"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Достапна е сателитска врска"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Сателитски SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Итни повици или SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"нема сигнал"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"една цртичка"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"внесете уред"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Користете отпечаток за да се отвори"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна е проверка. Допрете го сензорот за отпечаток за да автентицирате."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Тековен повик"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилен интернет"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Поврзано"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено поврзано"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Тековна апликација"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Кратенки од тастатура"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Приспособете ги кратенките од тастатурата"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Приспособете ги кратенките"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Да се отстрани кратенката?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Да се ресетира на стандардните поставки?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Притиснете копче за да доделите кратенка"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Комбинацијата на копчиња веќе се користи. Обидете се со друго копче."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Кратенката не може да се постави."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Додај кратенка"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Избриши кратенка"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Движете се со користење на тастатурата"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Научете ги кратенките од тастатурата"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Движете се со користење на допирната подлога"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index 601e6a13e628..4885595c860b 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"സാറ്റലൈറ്റ്, മികച്ച കണക്ഷൻ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"സാറ്റലൈറ്റ്, കണക്ഷൻ ലഭ്യമാണ്"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"സാറ്റലൈറ്റ് SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"എമർജൻസി കോൾ അല്ലെങ്കിൽ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"സിഗ്നൽ ഇല്ല"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ഒരു ബാർ"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ഉപകരണം നൽകുക"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"തുറക്കുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"പരിശോധിച്ചുറപ്പിക്കേണ്ടതുണ്ട്. പരിശോധിച്ചുറപ്പിക്കാൻ, വിരലടയാള സെൻസറിൽ സ്പർശിക്കുക."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"കോളിലാണ്"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"മൊബൈൽ ഡാറ്റ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"കണക്റ്റ് ചെയ്തു"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"താൽക്കാലികമായി കണക്റ്റ് ചെയ്തിരിക്കുന്നു"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"നിലവിലെ ആപ്പ്"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"കീബോഡ് കുറുക്കുവഴികൾ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"കീബോർഡ് കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"കുറുക്കുവഴികൾ ഇഷ്ടാനുസൃതമാക്കുക"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"കുറുക്കുവഴി നീക്കം ചെയ്യണോ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ഡിഫോൾട്ടിലേക്ക് തിരികെ റീസെറ്റ് ചെയ്യണോ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"കുറുക്കുവഴി അസൈൻ ചെയ്യാൻ കീ അമർത്തുക"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"കീ കോമ്പിനേഷൻ ഇതിനകം ഉപയോഗത്തിലുണ്ട്. മറ്റൊരു കീ പരീക്ഷിക്കുക."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"കുറുക്കുവഴി സജ്ജീകരിക്കാനാകില്ല."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"കുറുക്കുവഴി ചേർക്കുക"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"കുറുക്കുവഴി ഇല്ലാതാക്കുക"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"നിങ്ങളുടെ കീബോർഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"കീബോർഡ് കുറുക്കുവഴികൾ മനസ്സിലാക്കുക"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"നിങ്ങളുടെ ടച്ച്പാഡ് ഉപയോഗിച്ച് നാവിഗേറ്റ് ചെയ്യുക"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index b865eedbf26e..52dff9e8afdd 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хиймэл дагуул, холболт сайн байна"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Хиймэл дагуул, холболт боломжтой"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Хиймэл дагуул SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Яаралтай дуудлага эсвэл SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"дохио байхгүй"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"нэг шон"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Нээхийн тулд хурууны хээг ашиглана уу"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Баталгаажуулалт шаардлагатай. Баталгаажуулахын тулд хурууны хээ мэдрэгчид хүрнэ үү."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Үргэлжилж буй дуудлага"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобайл дата"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Холбогдсон"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Түр зуур холбогдсон"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Одоогийн апп"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Товчлуурын шууд холбоос"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Товчлуурын шууд холбоосыг өөрчлөх"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Товчлолыг өөрчлөх"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Товчлолыг хасах уу?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Өгөгдмөл рүү буцааж шинэчлэх үү?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Товчлол оноохын тулд товч дарна уу"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Товчийн хослолыг аль хэдийн ашиглаж байна. Өөр товч туршиж үзнэ үү."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Товчлол тохируулах боломжгүй."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Товчлол нэмэх"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Товчлол устгах"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Гараа ашиглан шилжих"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Товчлуурын шууд холбоосыг мэдэж аваарай"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Мэдрэгч самбараа ашиглан шилжээрэй"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index e257ba159788..85ae835df9fe 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"सॅटेलाइट, चांगले कनेक्शन"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"सॅटेलाइट, कनेक्शन उपलब्ध"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"सॅटेलाइट SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आणीबाणी कॉल किंवा SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"कोणताही सिग्नल नाही"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"एक बार"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिव्हाइस एंटर करा"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"उघडण्यासाठी फिंगरप्रिंट वापरा"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ऑथेंटिकेशन आवश्यक आहे. ऑथेंटिकेट करण्यासाठी फिंगरप्रिंट सेन्सरला स्पर्श करा."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"सुरू असलेला कॉल"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"कनेक्ट केले आहे"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"तात्पुरते कनेक्ट केलेले"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"सध्याचे अॅप"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अॅक्सेसिबिलिटी"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"कीबोर्ड शॉर्टकट"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"कीबोर्ड शॉर्टकट कस्टमाइझ करा"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"शॉर्टकट कस्टमाइझ करा"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"शॉर्टकट काढून टाकायचा आहे का?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"डीफॉल्टवर पुन्हा रीसेट करायचे आहे का?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"शॉर्टकट असाइन करण्यासाठी की प्रेस करा"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"की कॉम्बिनेशन आधीपासून वापरले जात आहे. दुसरी की वापरून पहा."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"शॉर्टकट सेट करू शकत नाही."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"शॉर्टकट जोडा"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"शॉर्टकट हटवा"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"तुमचा कीबोर्ड वापरून नेव्हिगेट करा"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"कीबोर्ड शॉर्टकट जाणून घ्या"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"तुमचा टचपॅड वापरून नेव्हिगेट करा"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index bf65859aab7e..b5f0d147f972 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, sambungan yang baik"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, sambungan tersedia"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via Satelit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Panggilan kecemasan atau SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"tiada isyarat"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"satu bar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"akses peranti"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gunakan cap jari untuk membuka"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Pengesahan diperlukan. Sentuh penderia cap jari untuk pengesahan."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Panggilan sedang berlangsung"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data mudah alih"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Disambungkan"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Disambungkan buat sementara waktu"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Apl Semasa"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Pintasan papan kekunci"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sesuaikan pintasan papan kekunci"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Sesuaikan pintasan"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alih keluar pintasan?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Tetapkan kembali kepada lalai?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tekan kekunci untuk menetapkan pintasan"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Gabungan kekunci sudah digunakan. Cuba kekunci lain."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Pintasan tidak boleh ditetapkan."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Tambahkan pintasan"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Padamkan pintasan"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigasi menggunakan papan kekunci"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Ketahui pintasan papan kekunci"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigasi menggunakan pad sentuh anda"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 1c4055687d26..d24c4a0b1631 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ကောင်းသည်"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ဂြိုဟ်တု၊ ချိတ်ဆက်မှု ရနိုင်သည်"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"အရေးပေါ်ဖုန်းခေါ်ခြင်း (သို့) SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>၊ <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>။"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"လိုင်းမရှိပါ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"တစ်ဘား"</string> @@ -830,7 +831,7 @@ <string name="keyboard_key_button_template" msgid="8005673627272051429">"ခလုတ် <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="keyboard_key_home" msgid="3734400625170020657">"ပင်မ"</string> <string name="keyboard_key_back" msgid="4185420465469481999">"နောက်သို့"</string> - <string name="keyboard_key_tab" msgid="4592772350906496730">"တဘ်ခလုတ်"</string> + <string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string> <string name="keyboard_key_space" msgid="6980847564173394012">"Space"</string> <string name="keyboard_key_enter" msgid="8633362970109751646">"Enter ခလုတ်"</string> <string name="keyboard_key_backspace" msgid="4095278312039628074">"နောက်ပြန်ခလုတ်"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"စက်ပစ္စည်းသို့ ဝင်ရန်"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ဖွင့်ရန် လက်ဗွေကို သုံးပါ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"အထောက်အထားစိစစ်ခြင်း လိုအပ်သည်။ အထောက်အထားစိစစ်ရန် လက်ဗွေ အာရုံခံကိရိယာကို ထိပါ။"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"လက်ရှိခေါ်ဆိုမှု"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"မိုဘိုင်းဒေတာ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ချိတ်ဆက်ထားသည်"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ယာယီချိတ်ဆက်ထားသည်"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"လက်ရှိအက်ပ်"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"လက်ကွက်ဖြတ်လမ်းများ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"လက်ကွက်ဖြတ်လမ်းများကို စိတ်ကြိုက်လုပ်ခြင်း"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ဖြတ်လမ်းများ စိတ်ကြိုက်ပြင်ဆင်ခြင်း"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ဖြတ်လမ်းလင့်ခ် ဖယ်ရှားမလား။"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"မူရင်းသို့ ပြန်လည်ပြင်ဆင်သတ်မှတ်မလား။"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ဖြတ်လမ်းလင့်ခ်သတ်မှတ်ရန် ကီးကို နှိပ်ပါ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ကီးပေါင်းစပ်ခြင်းကို သုံးနေပြီးဖြစ်သည်။ အခြားကီးကို စမ်းကြည့်ပါ။"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ဖြတ်လမ်းလင့်ခ် သတ်မှတ်၍မရပါ။"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ဖြတ်လမ်းလင့်ခ် ထည့်ရန်"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ဖြတ်လမ်းလင့်ခ် ဖျက်ရန်"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"သင့်ကီးဘုတ်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"လက်ကွက်ဖြတ်လမ်းများကို လေ့လာပါ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"သင့်တာ့ချ်ပက်ကိုသုံး၍ လမ်းညွှန်ခြင်း"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 0b68bd921c6f..871ffe921f89 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellitt – god tilkobling"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellitt – tilkobling tilgjengelig"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-alarm via satellitt"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nødanrop eller SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ikke noe signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"én strek"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"åpne enheten"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Bruk fingeravtrykk for å åpne"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentisering kreves. Trykk på fingeravtrykkssensoren for å autentisere."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktiv samtale"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Tilkoblet"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Koblet til midlertidig"</string> @@ -1437,13 +1437,13 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktiv app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Hurtigtaster"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tilpass hurtigtastene"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Tilpass snarveier"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vil du fjerne hurtigtasten?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vil du tilbakestille til standard?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Trykk på en tast for å tilordne hurtigtasten"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Dette fører til at den egendefinerte hurtigtasten slettes permanent."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Dette fører til at alle de egendefinerte snarveiene dine slettes permanent."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Snarveier til søk"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Søk etter snarveier"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Ingen søkeresultater"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Skjul-ikon"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Handlings- eller Meta-tast-ikon"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tastekombinasjonen brukes allerede. Prøv en annen tast."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Kan ikke angi snarveien."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Legg til snarvei"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Slett snarveien"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Naviger med tastaturet"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lær deg hurtigtaster"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Naviger med styreflaten"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 818809b4acfc..58307c49ada7 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"स्याटलाइट, राम्रो कनेक्सन"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"स्याटलाइट, कनेक्सन उपलब्ध छ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"स्याटलाइट SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"आपत्कालीन कल वा SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>।"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"सिग्नल छैन"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"एउटा बार"</string> @@ -884,7 +885,7 @@ <string name="group_system_access_google_assistant" msgid="7210074957915968110">"एसिस्टेन्ट खोल्नुहोस्"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"स्क्रिन लक गर्नुहोस्"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"नोट लेख्नुहोस्"</string> - <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"एकै पटक एकभन्दा बढी एप चलाउन मिल्ने सुविधा"</string> + <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"मल्टिटास्किङ"</string> <string name="system_multitasking_rhs" msgid="8779289852395243004">"हालको एप दायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"हालको एप बायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string> <string name="system_multitasking_full_screen" msgid="4940465971687159429">"फुल स्क्रिन प्रयोग गर्नुहोस्"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"फिंगरप्रिन्ट प्रयोग गरी खोल्नुहोस्"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"पुष्टि गर्नु पर्ने हुन्छ। पुष्टि गर्न फिंगरप्रिन्ट सेन्सर छुनुहोस्।"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"कल भइरहेको"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"मोबाइल डेटा"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"इन्टरनेटमा कनेक्ट गरिएको छ"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"यसमा केही समयका लागि कनेक्ट गरिएको हो"</string> @@ -1430,20 +1430,20 @@ <string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string> <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टमसँग सम्बन्धित नियन्त्रणहरू"</string> <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम एपहरू"</string> - <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"एकै पटक एकभन्दा बढी एप चलाउन मिल्ने सुविधा"</string> + <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टिटास्किङ"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रिन"</string> <string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string> <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"एपका सर्टकटहरू"</string> <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"हालको एप"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"किबोर्डका सर्टकटहरू"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"किबोर्डका सर्टकटहरू कस्टमाइज गर्नुहोस्"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"सर्टकटहरू कस्टमाइज गर्नुहोस्"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"सर्टकट हटाउने हो?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"सर्टकट रिसेट गरी डिफल्ट बनाउने हो?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"सर्टकट असाइन गर्न की थिच्नुहोस्"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"यसो गर्नुभयो भने तपाईंको कस्टम सर्टकट सदाका लागि मेटिने छ।"</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"तपाईंले यसो गर्नुभयो भने तपाईंका सबै कस्टम सर्टकटहरू सदाका लागि मेटाइने छन्।"</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"खोजका सर्टकटहरू"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"सर्टकटहरू खोज्नुहोस्"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"कुनै पनि खोज परिणाम भेटिएन"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"\"कोल्याप्स गर्नुहोस्\" आइकन"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"एक्सन वा Meta कीको आइकन"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"यो की कम्बिनेसन प्रयोग गरिसकिएको छ। अर्कै की प्रयोग गरी हेर्नुहोस्।"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"सर्टकट सेट गर्न सकिएन।"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"सर्टकट हाल्नुहोस्"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"सर्टकट मेटाउनुहोस्"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"किबोर्ड प्रयोग गरी नेभिगेट गर्नुहोस्"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"किबोर्डका सर्टकटहरू प्रयोग गर्न सिक्नुहोस्"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"टचप्याड प्रयोग गरी नेभिगेट गर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 546cd081af72..6e8d328c1896 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelliet, goede verbinding"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelliet, verbinding beschikbaar"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satelliet"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Noodoproepen of SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"geen signaal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 streepje"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gebruik vingerafdruk om te openen"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Verificatie vereist. Raak de vingerafdruksensor aan om de verificatie uit te voeren."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Actief gesprek"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobiele data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Verbonden"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tijdelijk verbonden"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Huidige app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Sneltoetsen"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Sneltoetsen aanpassen"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Snelkoppelingen aanpassen"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Sneltoets verwijderen?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Resetten naar standaard?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Druk op de toets om de sneltoets toe te wijzen"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Toetsencombinatie is al in gebruik. Probeer een andere toets."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Sneltoets kan niet worden ingesteld."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Snelkoppeling toevoegen"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Snelkoppeling verwijderen"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigeren met je toetsenbord"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Leer sneltoetsen die je kunt gebruiken"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigeren met je touchpad"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index d035f6a88de0..9986c11b49fd 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ସାଟେଲାଇଟ, ଭଲ କନେକ୍ସନ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ସାଟେଲାଇଟ, କନେକ୍ସନ ଉପଲବ୍ଧ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ସେଟେଲାଇଟ SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ଜରୁରୀକାଳୀନ କଲ କିମ୍ବା SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>।"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"କୌଣସି ସିଗନାଲ ନାହିଁ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ଗୋଟିଏ ବାର"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ଖୋଲିବାକୁ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ପ୍ରମାଣୀକରଣ ଆବଶ୍ୟକ। ପ୍ରମାଣୀକରଣ କରିବାକୁ ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ସ୍ପର୍ଶ କରନ୍ତୁ।"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ଚାଲିଥିବା କଲ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ମୋବାଇଲ ଡାଟା"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ସଂଯୋଗ କରାଯାଇଛି"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ଅସ୍ଥାୟୀ ରୂପେ କନେକ୍ଟ କରାଯାଇଛି"</string> @@ -1428,7 +1428,7 @@ <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string> <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ଏବେ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି"</string> <string name="shortcut_helper_category_system" msgid="462110876978937359">"ସିଷ୍ଟମ"</string> - <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ସିଷ୍ଟମ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> + <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ସିଷ୍ଟମ କଣ୍ଟ୍ରୋଲ"</string> <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ସିଷ୍ଟମ ଆପ୍ସ"</string> <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ମଲ୍ଟିଟାସ୍କିଂ"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ବର୍ତ୍ତମାନର ଆପ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"କୀବୋର୍ଡ ସର୍ଟକଟ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ସର୍ଟକଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ସର୍ଟକଟକୁ କାଢ଼ି ଦେବେ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ଡିଫଲ୍ଟରେ ପୁଣି ରିସେଟ କରିବେ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ସର୍ଟକଟ ଆସାଇନ କରିବା ପାଇଁ କୀ\'କୁ ଦବାନ୍ତୁ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"କୀ କମ୍ବିନେସନ ପୂର୍ବରୁ ବ୍ୟବହାର କରାଯାଉଛି। ଅନ୍ୟ ଏକ କୀ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ।"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ସର୍ଟକଟ ସେଟ କରାଯାଇପାରିବ ନାହିଁ।"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ସର୍ଟକଟ ଯୋଗ କରନ୍ତୁ"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ସର୍ଟକଟକୁ ଡିଲିଟ କରନ୍ତୁ"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ଆପଣଙ୍କ କୀବୋର୍ଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"କୀବୋର୍ଡ ସର୍ଟକଟଗୁଡ଼ିକ ବିଷୟରେ ଜାଣନ୍ତୁ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ଆପଣଙ୍କ ଟଚପେଡ ବ୍ୟବହାର କରି ନାଭିଗେଟ କରନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 7b718de7f074..45888847bc2e 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -351,7 +351,7 @@ <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ਚਮਕ"</string> <string name="quick_settings_inversion_label" msgid="3501527749494755688">"ਰੰਗ ਪਲਟਨਾ"</string> <string name="quick_settings_color_correction_label" msgid="5636617913560474664">"ਰੰਗ ਸੁਧਾਈ"</string> - <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ਫੌਂਟ ਦਾ ਆਕਾਰ"</string> + <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ਫੌਂਟ ਸਾਈਜ਼"</string> <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="quick_settings_done" msgid="2163641301648855793">"ਹੋ ਗਿਆ"</string> <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"ਬੰਦ ਕਰੋ"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਵਧੀਆ ਹੈ"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ਸੈਟੇਲਾਈਟ, ਕਨੈਕਸ਼ਨ ਉਪਲਬਧ ਹੈ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ਸੈਟੇਲਾਈਟ SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਜਾਂ ਸਹਾਇਤਾ"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ਕੋਈ ਸਿਗਨਲ ਨਹੀਂ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ਇੱਕ ਸਿਗਨਲ ਪੱਟੀ"</string> @@ -1069,7 +1070,7 @@ <string name="privacy_type_media_projection" msgid="8136723828804251547">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ"</string> <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"ਸਟੈਂਡਬਾਈ"</string> - <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ਫ਼ੌਂਟ ਦਾ ਆਕਾਰ"</string> + <string name="font_scaling_dialog_title" msgid="6273107303850248375">"ਫ਼ੌਂਟ ਸਾਈਜ਼"</string> <string name="font_scaling_smaller" msgid="1012032217622008232">"ਛੋਟਾ ਕਰੋ"</string> <string name="font_scaling_larger" msgid="5476242157436806760">"ਵੱਡਾ ਕਰੋ"</string> <string name="magnification_window_title" msgid="4863914360847258333">"ਵੱਡਦਰਸ਼ੀਕਰਨ Window"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ਖੋਲ੍ਹਣ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ਪ੍ਰਮਾਣੀਕਰਨ ਲੋੜੀਂਦਾ ਹੈ। ਪ੍ਰਮਾਣਿਤ ਕਰਨ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪਰਸ਼ ਕਰੋ।"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"ਜਾਰੀ ਕਾਲ"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ਮੋਬਾਈਲ ਡਾਟਾ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"ਕਨੈਕਟ ਹੈ"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"ਕੁਝ ਸਮੇਂ ਲਈ ਕਨੈਕਟ ਹੈ"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ਮੌਜੂਦਾ ਐਪ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ਸ਼ਾਰਟਕੱਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ਕੀ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ਕੀ ਵਾਪਸ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ \'ਤੇ ਰੀਸੈੱਟ ਕਰਨਾ ਹੈ?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ਸ਼ਾਰਟਕੱਟ ਨਿਰਧਾਰਿਤ ਕਰਨ ਲਈ ਕੁੰਜੀ ਦਬਾਓ"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"ਕੁੰਜੀ ਸੁਮੇਲ ਪਹਿਲਾਂ ਹੀ ਵਰਤੋਂ ਵਿੱਚ ਹੈ। ਕੋਈ ਹੋਰ ਕੁੰਜੀ ਵਰਤ ਕੇ ਦੇਖੋ।"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਸੈੱਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰੋ"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ਸ਼ਾਰਟਕੱਟ ਮਿਟਾਓ"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ਆਪਣੇ ਕੀ-ਬੋਰਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ਕੀ-ਬੋਰਡ ਦੇ ਸ਼ਾਰਟਕੱਟਾਂ ਬਾਰੇ ਜਾਣੋ"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ਆਪਣੇ ਟੱਚਪੈਡ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਨੈਵੀਗੇਟ ਕਰੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index b6dc2f61656c..67ca4393ee64 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelita – połączenie dobre"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelita – połączenie dostępne"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satelitarne połączenie alarmowe"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Połączenia alarmowe lub SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"brak sygnału"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 pasek"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"By otworzyć, użyj odcisku palca"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Wymagane uwierzytelnienie. Dotknij czytnika liniii papilarnych, by uwierzytelnić."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Trwa rozmowa"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilna transmisja danych"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Połączono"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tymczasowe połączenie"</string> @@ -1437,13 +1437,13 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Bieżąca aplikacja"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Skróty klawiszowe"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Dostosuj skróty klawiszowe"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Dostosuj skróty"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Usunąć skrót?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Zresetować do ustawień domyślnych?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Naciśnij klawisz, aby przypisać skrót"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Spowoduje to trwałe usunięcie skrótu niestandardowego."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Spowoduje to trwałe usunięcie wszystkich skrótów niestandardowych."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Skróty do wyszukiwania"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Szukaj skrótów"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Brak wyników wyszukiwania"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Ikona zwijania"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"Ikona klawisza działania/meta"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ta kombinacja klawiszy jest już używana. Użyj innego klawisza."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Nie można ustawić skrótu."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Dodaj skrót"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Usuń skrót"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Nawiguj za pomocą klawiatury"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Dowiedz się więcej o skrótach klawiszowych"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Nawiguj za pomocą touchpada"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index e7bcaa25e7fb..ead72a21e432 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -688,7 +688,7 @@ <string name="stream_system" msgid="7663148785370565134">"Sistema"</string> <string name="stream_ring" msgid="7550670036738697526">"Toques"</string> <string name="stream_music" msgid="2188224742361847580">"Mídia"</string> - <string name="stream_alarm" msgid="16058075093011694">"Alarme"</string> + <string name="stream_alarm" msgid="16058075093011694">"Alarmes"</string> <string name="stream_notification" msgid="7930294049046243939">"Notificações"</string> <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string> <string name="stream_dtmf" msgid="7322536356554673067">"Multifrequência de dois tons"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satélite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"sem sinal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"uma barra"</string> @@ -871,7 +872,7 @@ <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Mostrando atalhos de entrada"</string> <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Mostrando atalhos que abrem apps"</string> <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Mostrando atalhos do app atual"</string> - <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Mostrar as notificações"</string> + <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificações"</string> <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fazer uma captura de tela"</string> <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string> <string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em andamento"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporariamente conectado"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar atalhos"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remover atalho?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Redefinir para o padrão?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pressione a tecla para atribuir o atalho"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Essa combinação de teclas já está em uso. Tente outra tecla."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Não é possível definir o atalho."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Adicionar atalho"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Excluir atalho"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index a9de96156d5b..303a2808d552 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, boa ligação"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, ligação disponível"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satélite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"sem sinal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 barra"</string> @@ -883,7 +884,7 @@ <string name="group_system_access_system_settings" msgid="8731721963449070017">"Abrir definições"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Abrir Assistente"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Ecrã de bloqueio"</string> - <string name="group_system_quick_memo" msgid="3764560265935722903">"Tire notas"</string> + <string name="group_system_quick_memo" msgid="3764560265935722903">"Tirar notas"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Execução de várias tarefas em simultâneo"</string> <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use o ecrã dividido com a app à direita"</string> <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use o ecrã dividido com a app à esquerda"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Utilize a impressão digital para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação necessária. Toque no sensor de impressões digitais para autenticar."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em curso"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ligado"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ligado temporariamente"</string> @@ -1430,14 +1430,14 @@ <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string> <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlos do sistema"</string> <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string> - <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Execução de várias tarefas em simultâneo"</string> + <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecrã dividido"</string> <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string> <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string> <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos de teclado"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalize os atalhos de teclado"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalize os atalhos"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remover atalho?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Repor para a predefinição?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Prima a tecla para atribuir o atalho"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"A combinação de teclas já está a ser usada. Experimente outra tecla."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Não é possível definir o atalho."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Adicionar atalho"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Eliminar atalho"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue com o teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos de teclado"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue com o touchpad"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index e7bcaa25e7fb..ead72a21e432 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -688,7 +688,7 @@ <string name="stream_system" msgid="7663148785370565134">"Sistema"</string> <string name="stream_ring" msgid="7550670036738697526">"Toques"</string> <string name="stream_music" msgid="2188224742361847580">"Mídia"</string> - <string name="stream_alarm" msgid="16058075093011694">"Alarme"</string> + <string name="stream_alarm" msgid="16058075093011694">"Alarmes"</string> <string name="stream_notification" msgid="7930294049046243939">"Notificações"</string> <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string> <string name="stream_dtmf" msgid="7322536356554673067">"Multifrequência de dois tons"</string> @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satélite, conexão boa"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satélite, conexão disponível"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS via satélite"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Chamadas de emergência ou SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"sem sinal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"uma barra"</string> @@ -871,7 +872,7 @@ <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Mostrando atalhos de entrada"</string> <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Mostrando atalhos que abrem apps"</string> <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Mostrando atalhos do app atual"</string> - <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Mostrar as notificações"</string> + <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Ver notificações"</string> <string name="group_system_full_screenshot" msgid="5742204844232667785">"Fazer uma captura de tela"</string> <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Mostrar atalhos"</string> <string name="group_system_go_back" msgid="2730322046244918816">"Voltar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Use a impressão digital para abrir"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autenticação obrigatória. Toque no sensor de impressão digital para autenticar."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Chamada em andamento"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dados móveis"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectado"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Temporariamente conectado"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"App atual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Atalhos do teclado"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizar atalhos de teclado"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizar atalhos"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Remover atalho?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Redefinir para o padrão?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pressione a tecla para atribuir o atalho"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Essa combinação de teclas já está em uso. Tente outra tecla."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Não é possível definir o atalho."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Adicionar atalho"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Excluir atalho"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navegue usando o teclado"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Aprenda atalhos do teclado"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navegue usando o touchpad"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 7fb1169af6f9..afd18f12cbf5 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, conexiune bună"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, conexiune disponibilă"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS prin satelit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Apeluri de urgență sau SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"fără semnal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"o bară"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"Accesează dispozitivul"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Folosește amprenta ca să deschizi"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentificare obligatorie. Atinge senzorul de amprentă pentru a te autentifica."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Apel în desfășurare"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Date mobile"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Conectat"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectat temporar"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplicația actuală"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Comenzi rapide de la tastatură"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizează comenzile rapide de la tastatură"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Personalizează comenzile rapide"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Elimini comanda rapidă?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Resetezi la valorile prestabilite?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Apasă tasta pentru a atribui comanda rapidă"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Combinația de taste este deja folosită. Încearcă altă tastă."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Comanda rapidă nu poate fi setată."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Adaugă o comandă rapidă"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Șterge comanda rapidă"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navighează folosind tastatura"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Învață comenzile rapide de la tastatură"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navighează folosind touchpadul"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 448c2457efe1..10dc51d71683 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Спутниковая связь, хорошее качество соединения"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступно соединение по спутниковой связи"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Спутниковый SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Экстренные вызовы или спутниковый SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"нет сигнала"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"одно деление"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"указать устройство"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Используйте отпечаток пальца для входа."</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Требуется аутентификация. Приложите палец к сканеру отпечатков."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Текущий вызов"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобильный интернет"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Подключено"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Временное подключение"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Это приложение"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Сочетания клавиш"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Настройки сочетаний клавиш"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Настройки сочетаний клавиш"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Удалить сочетание клавиш?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Сбросить настройки?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Нажмите клавишу, чтобы назначить сочетание клавиш."</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Это сочетание клавиш уже используется. Попробуйте другое."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Это сочетание клавиш выбрать нельзя."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Добавить сочетание клавиш"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Удалить сочетание клавиш"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навигация с помощью клавиатуры"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Узнайте о сочетаниях клавиш."</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навигация с помощью сенсорной панели"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index d5c90b566ad6..5a7a6a377527 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"චන්ද්රිකාව, හොඳ සම්බන්ධතාවයක්"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"චන්ද්රිකාව, සම්බන්ධතාවය තිබේ"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"චන්ද්රිකා SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"හදිසි ඇමතුම් හෝ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"සංඥාව නැත"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"තීරු එකක්"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"උපාංගය ඇතුළු කරන්න"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"විවෘත කිරීමට ඇඟිලි සලකුණ භාවිත කරන්න"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"සත්යාපනය අවශ්යයි. සත්යාපනය කිරීමට ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"කර ගෙන යන ඇමතුම"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"ජංගම දත්ත"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"සම්බන්ධයි"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"තාවකාලිකව සම්බන්ධ කළා"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"වත්මන් යෙදුම"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්රවේශ්යතාව"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"යතුරු පුවරු කෙටි මං"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"යතුරුපුවරු කෙටිමං අභිරුචිකරණය කරන්න"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"කෙටිමඟ ඉවත් කරන්න ද?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"පෙරනිමියට යළි සකසන්න ද?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"කෙටිමඟ පැවරීමට යතුර ඔබන්න"</string> @@ -1465,6 +1466,10 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"යතුරු සංයෝජනය දැනටමත් භාවිත වේ. වෙනත් යතුරක් උත්සාහ කරන්න."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"කෙටිමඟ සැකසිය නොහැක."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <!-- no translation found for shortcut_helper_add_shortcut_button_label (7655779534665954910) --> + <skip /> + <!-- no translation found for shortcut_helper_delete_shortcut_button_label (3148773472696137052) --> + <skip /> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ඔබේ යතුරු පුවරුව භාවිතයෙන් සංචාලනය කරන්න"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"යතුරුපුවරු කෙටිමං ඉගෙන ගන්න"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ඔබේ ස්පර්ශ පෑඩ් භාවිතයෙන් සංචාලනය කරන්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index af84fd19bb0c..d2d9cdeed413 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobrá kvalita pripojenia"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, pripojenie je k dispozícii"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Pomoc cez satelit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Tiesňové volania alebo pomoc v tiesni"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"žiadny signál"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"jedna čiarka"</string> @@ -881,7 +882,7 @@ <string name="group_system_cycle_back" msgid="8194102916946802902">"Cyklické prechádzanie dozadu nedávnymi aplikáciami"</string> <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Otvorenie zoznamu aplikácií"</string> <string name="group_system_access_system_settings" msgid="8731721963449070017">"Otvorenie nastavení"</string> - <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvoriť asistenta"</string> + <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Otvorenie Asistenta"</string> <string name="group_system_lock_screen" msgid="7391191300363416543">"Uzamknutie obrazovky"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"Napísanie poznámky"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitasking"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"vstúpte do zariadenia"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Otvorte odtlačkom prsta"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Vyžaduje sa overenie. Dotknite sa senzora odtlačkov prstov."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Prebiehajúci hovor"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobilné dáta"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Pripojené"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasne pripojené"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuálna aplikácia"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Klávesové skratky"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prispôsobenie klávesových skratiek"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Prispôsobenie skratiek"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Chcete skratku odstrániť?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Chcete resetovať na predvolené nastavenie?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Stlačením klávesa priraďte skratku"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinácia klávesov sa už používa. Skúste iný kláves."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Skratku nie je možné nastaviť."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Pridať skratku"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Odstrániť skratku"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Pohybujte sa v systéme pomocou klávesnice"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Naučte sa klávesové skratky"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Pohybujte sa v systéme pomocou touchpadu"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 1242774768b3..c473962ca1ba 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satelit, dobra povezava"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satelit, povezava je na voljo"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS prek satelita"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Klici v sili ali SOS prek satelita"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ni signala"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ena črtica"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"vstop v napravo"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Odprite s prstnim odtisom"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Zahtevano je preverjanje pristnosti. Za preverjanje pristnosti se dotaknite tipala prstnih odtisov."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Aktivni klic"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Prenos podatkov v mobilnem omrežju"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Povezano"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Začasno vzpostavljena povezava"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Trenutna aplikacija"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Bližnjične tipke"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Prilagajanje bližnjičnih tipk"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Prilagajanje bližnjic"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Želite odstraniti bližnjico?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Želite ponastaviti na privzete bližnjice?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pritisnite tipko za dodelitev bližnjice"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinacija tipk je že v uporabi. Poskusite z drugo tipko."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Bližnjice ni mogoče nastaviti."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Dodajanje bližnjice"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Izbris bližnjice"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Krmarjenje s tipkovnico"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Učenje bližnjičnih tipk"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Krmarjenje s sledilno ploščico"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index c3d13539e1f9..3c7d05b2e318 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sateliti. Lidhje e mirë"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sateliti. Ofrohet lidhje"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS satelitor"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Telefonatat e urgjencës ose SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"nuk ka sinjal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"një vijë"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"për të hyrë në pajisje"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Përdor gjurmën e gishtit për ta hapur"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kërkohet vërtetimi. Prek sensorin e gjurmës së gishtit për t\'u vërtetuar."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Telefonatë në vazhdim"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Të dhënat celulare"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Lidhur"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Lidhur përkohësisht"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aplikacioni aktual"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Shkurtoret e tastierës"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Personalizo shkurtoret e tastierës"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Të hiqet shkurtorja?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Të rivendosen përsëri te parazgjedhjet?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Shtyp tastin për të caktuar shkurtoren"</string> @@ -1465,6 +1466,10 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Kombinimi i tasteve është tashmë në përdorim. Provo një tast tjetër."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Shkurtorja nuk mund të caktohet."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <!-- no translation found for shortcut_helper_add_shortcut_button_label (7655779534665954910) --> + <skip /> + <!-- no translation found for shortcut_helper_delete_shortcut_button_label (3148773472696137052) --> + <skip /> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigo duke përdorur tastierën tënde"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Mëso shkurtoret e tastierës"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigo duke përdorur bllokun me prekje"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 344b012c2c80..b7ddd4d7c6d2 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Сателит, веза је добра"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Сателит, веза је доступна"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Хитна помоћ преко сателита"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Хитни позиви или хитна помоћ"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"нема сигнала"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"једна црта"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Отворите помоћу отиска прста"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Потребна је потврда идентитета. Додирните сензор за отисак прста да бисте потврдили идентитет."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Позив је у току"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобилни подаци"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Повезано"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Привремено повезано"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Актуелна апликација"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Тастерске пречице"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Прилагодите тастерске пречице"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Прилагодите пречице"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Желите да уклоните пречицу?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Желите да ресетујете на подразумевано?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Притисните тастер да бисте доделили пречицу"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Комбинација тастера се већ користи. Пробајте са другим тастером."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Подешавање пречице није успело."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Додајте пречицу"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Избришите пречицу"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Крећите се помоћу тастатуре"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Сазнајте више о тастерским пречицама"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Крећите се помоћу тачпеда"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 4d862d9842a8..2d2a94d4e7b2 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellit, bra anslutning"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellit, anslutning tillgänglig"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS-larm via satellit"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Nödsamtal eller SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ingen signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"en stapel"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ange enhet"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Öppna med fingeravtryck"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Autentisering krävs. Identifiera dig genom att trycka på fingeravtryckssensorn."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Pågående samtal"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobildata"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ansluten"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tillfälligt ansluten"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Aktuell app"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Kortkommandon"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Anpassa kortkommandon"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Anpassa kortkommandon"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Vill du ta bort kortkommandot?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Vill du återställa till standardinställningarna?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tryck på tangenten för att tilldela ett kortkommando"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tangentkombinationen används redan. Testa en annan tangent."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Det går inte att ställa in kortkommandot."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Lägg till genväg"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Radera genväg"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Navigera med tangentbordet"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Lär dig kortkommandon"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Navigera med styrplattan"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 731765437ced..424434d182a7 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Setilaiti, muunganisho thabiti"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Setilaiti, muunganisho unapatikana"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Msaada kupitia Setilaiti"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Simu za dharura"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"hakuna mtandao"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"upau mmoja"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"weka kifaa"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Tumia alama ya kidole kufungua"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Uthibitishaji unahitajika. Gusa kitambua alama ya kidole ili uthibitishe."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Simu inayoendelea"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Data ya mtandao wa simu"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Imeunganishwa"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Imeunganishwa kwa muda"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Programu Inayotumika Sasa"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Mikato ya kibodi"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Weka mapendeleo ya mikato ya kibodi"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Kuweka mapendeleo ya njia za mkato"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Ungependa kuondoa njia ya mkato?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Ungependa kurejesha njia za mkato chaguomsingi?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Bonyeza kitufe ukabidhi njia ya mkato"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tayari unatumia mchanganyiko wa vitufe. Jaribu kitufe kingine."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Haiwezi kuweka njia ya mkato."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Weka njia ya mkato"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Futa njia ya mkato"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Kusogeza kwa kutumia kibodi yako"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Fahamu kuhusu mikato ya kibodi"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Kusogeza kwa kutumia padi yako ya kugusa"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 5a7defae136f..cb340789345e 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"சாட்டிலைட், நிலையான இணைப்பு"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"சாட்டிலைட், இணைப்பு கிடைக்கிறது"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"சாட்டிலைட் SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"அவசர அழைப்புகள் அல்லது SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"சிக்னல் இல்லை"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ஒரு கோடு"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"சாதனத்தைத் திற"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"கைரேகையைப் பயன்படுத்தி திறந்திடுங்கள்"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"அங்கீகாரம் தேவை. கைரேகை சென்சாரைத் தொட்டு அங்கீகரியுங்கள்."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"செயலில் உள்ள அழைப்பு"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"மொபைல் டேட்டா"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"இணைக்கப்பட்டது"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"தற்காலிகமாக இணைக்கப்பட்டுள்ளது"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"தற்போதைய ஆப்ஸ்"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"மாற்றுத்திறன் வசதி"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"கீபோர்டு ஷார்ட்கட்கள்"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"கீபோர்டு ஷார்ட்கட்களைப் பிரத்தியேகப்படுத்துதல்"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ஷார்ட்கட்களைப் பிரத்தியேகமாக்குதல்"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"ஷார்ட்கட்டை அகற்றவா?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"மீண்டும் இயல்புநிலைக்கு மீட்டமைக்கவா?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"ஷார்ட்கட்டை அமைக்க பட்டனை அழுத்துங்கள்"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"பட்டன் சேர்க்கை ஏற்கெனவே பயன்பாட்டில் உள்ளது. வேறொரு பட்டனைப் பயன்படுத்திப் பார்க்கவும்."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ஷார்ட்கட்டை அமைக்க முடியாது."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"ஷார்ட்கட்டைச் சேர்க்கும்"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ஷார்ட்கட்டை அகற்றும்"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"கீபோர்டைப் பயன்படுத்திச் செல்லுதல்"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"கீபோர்டு ஷார்ட்கட்கள் குறித்துத் தெரிந்துகொள்ளுங்கள்"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"டச்பேடைப் பயன்படுத்திச் செல்லுதல்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 1be6ce61a399..8dac7651ae49 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"శాటిలైట్, కనెక్షన్ బాగుంది"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"శాటిలైట్, కనెక్షన్ అందుబాటులో ఉంది"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"ఎమర్జెన్సీ శాటిలైట్ సహాయం"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ఎమర్జెన్సీ కాల్స్ లేదా SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"సిగ్నల్ లేదు"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"సిగ్నల్ ఒక బార్ ఉంది"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"పరికరాన్ని ఎంటర్ చేయండి"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"తెరవడానికి వేలిముద్రను ఉపయోగించండి"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ప్రామాణీకరణ అవసరం. ప్రామాణీకరించడానికి వేలిముద్ర సెన్సార్ను తాకండి."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"కాల్ కొనసాగుతోంది"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"మొబైల్ డేటా"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"కనెక్ట్ చేయబడింది"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"తాత్కాలికంగా కనెక్ట్ చేయబడింది"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"ప్రస్తుత యాప్"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"కీబోర్డ్ షార్ట్కట్లు"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"కీబోర్డ్ షార్ట్కట్లను అనుకూలంగా మార్చండి"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"షార్ట్కట్లను అనుకూలంగా మార్చండి"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"షార్ట్కట్ను తీసివేయాలా?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"తిరిగి ఆటోమేటిక్ సెట్టింగ్కు రీసెట్ చేయాలా?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"షార్ట్కట్ను కేటాయించడానికి కీని నొక్కండి"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"కీ కాంబినేషన్ ఇప్పటికే వినియోగంలో ఉంది. వేరొక కీని ట్రై చేయండి."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"షార్ట్కట్ను సెట్ చేయడం సాధ్యం కాదు."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"షార్ట్కట్ను జోడించండి"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"షార్ట్కట్ను తొలగించండి"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"మీ కీబోర్డ్ ఉపయోగించి నావిగేట్ చేయండి"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"కీబోర్డ్ షార్ట్కట్ల గురించి తెలుసుకోండి"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"మీ టచ్ప్యాడ్ను ఉపయోగించి నావిగేట్ చేయండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 3770addf98e3..cd111fd54d02 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"ดาวเทียม, การเชื่อมต่อดี"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"ดาวเทียม, การเชื่อมต่อที่พร้อมใช้งาน"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"SOS ดาวเทียม"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"การโทรฉุกเฉินหรือ SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ไม่มีสัญญาณ"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 ขีด"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"เข้าถึงอุปกรณ์"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ใช้ลายนิ้วมือเพื่อเปิด"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"ต้องมีการตรวจสอบสิทธิ์ แตะเซ็นเซอร์ลายนิ้วมือเพื่อตรวจสอบสิทธิ์"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"สายที่สนทนาอยู่"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"อินเทอร์เน็ตมือถือ"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"เชื่อมต่อแล้ว"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"เชื่อมต่อแล้วชั่วคราว"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"แอปปัจจุบัน"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"แป้นพิมพ์ลัด"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"ปรับแต่งแป้นพิมพ์ลัด"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"ปรับแต่งแป้นพิมพ์ลัด"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"นำแป้นพิมพ์ลัดออกใช่ไหม"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"รีเซ็ตกลับเป็นค่าเริ่มต้นไหม"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"กดแป้นเพื่อกำหนดแป้นพิมพ์ลัด"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"มีการใช้แป้นที่กดร่วมกันนี้แล้ว โปรดลองใช้แป้นอื่น"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"ตั้งค่าแป้นพิมพ์ลัดไม่ได้"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"เพิ่มทางลัด"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"ลบทางลัด"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"ไปยังส่วนต่างๆ โดยใช้แป้นพิมพ์"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"ดูข้อมูลเกี่ยวกับแป้นพิมพ์ลัด"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"ไปยังส่วนต่างๆ โดยใช้ทัชแพด"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index d28915eccb73..3c5448e20664 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Satellite, malakas ang koneksyon"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Satellite, may koneksyon"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Satellite SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Mga emergency na tawag o SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"walang signal"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"isang bar"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ilagay ang device"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Gamitin ang fingerprint para buksan"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kailangan ng pag-authenticate. Pindutin ang sensor para sa fingerprint para mag-authenticate."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Kasalukuyang tawag"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobile data"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Nakakonekta"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Pansamantalang nakakonekta"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Kasalukuyang App"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Mga keyboard shortcut"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"I-customize ang mga keyboard shortcut"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"I-customize ang mga shortcut"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Alisin ang shortcut?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"I-reset pabalik sa default?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Pindutin ang key para magtalaga ng shortcut"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Ginagamit na ang kumbinasyon ng key. Sumubok ng ibang key."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Hindi maitakda ang shortcut."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Maglagay ng shortcut"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Mag-delete ng shortcut"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Mag-navigate gamit ang iyong keyboard"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Matuto ng mga keyboard shortcut"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Mag-navigate gamit ang iyong touchpad"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 29a5763385bd..61ed4e54209b 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Uydu, bağlantı güçlü"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Uydu, bağlantı mevcut"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Acil Uydu Bağlantısı"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Acil durum aramaları veya acil yardım"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"sinyal yok"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"tek çubuk"</string> @@ -882,7 +883,7 @@ <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Uygulama listesini aç"</string> <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ayarları aç"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Asistan\'ı aç"</string> - <string name="group_system_lock_screen" msgid="7391191300363416543">"Kilit ekranı"</string> + <string name="group_system_lock_screen" msgid="7391191300363416543">"Ekranı kilitle"</string> <string name="group_system_quick_memo" msgid="3764560265935722903">"Not al"</string> <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Çoklu görev"</string> <string name="system_multitasking_rhs" msgid="8779289852395243004">"Sağdaki uygulamayla birlikte bölünmüş ekranı kullan"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz girin"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Açmak için parmak izi kullanın"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Kimlik doğrulaması gerekiyor. Kimlik doğrulaması için parmak izi sensörüne dokunun."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Devam eden arama"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil veri"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Bağlı"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Geçici olarak bağlandı"</string> @@ -1437,13 +1437,13 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Mevcut Uygulama"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Klavye kısayolları"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Klavye kısayollarını özelleştirin"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Kısayolları özelleştirin"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Kısayol kaldırılsın mı?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Varsayılan kısayollara sıfırlansın mı?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Kısayol atamak için tuşa basın"</string> <string name="shortcut_customize_mode_remove_shortcut_description" msgid="6851287900585057128">"Bu işlem, özel kısayolunuzu kalıcı olarak siler."</string> <string name="shortcut_customize_mode_reset_shortcut_description" msgid="2081849715634358684">"Bu işlem, tüm özel kısayollarınızı kalıcı olarak siler."</string> - <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Arama kısayolları"</string> + <string name="shortcut_helper_search_placeholder" msgid="5488547526269871819">"Kısayollarda ara"</string> <string name="shortcut_helper_no_search_results" msgid="8554756497996692160">"Arama sonucu yok"</string> <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Daralt simgesi"</string> <string name="shortcut_helper_content_description_meta_key" msgid="3989315044342124818">"İşlem veya Meta tuşu simgesi"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tuş kombinasyonu zaten kullanılıyor. Başka bir tuş deneyin."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Kısayol ayarlanamıyor."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Kısayol ekle"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Kısayolu sil"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klavyenizi kullanarak gezinin"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Klavye kısayollarını öğrenin"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Dokunmatik alanınızı kullanarak gezinin"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index ea839cc9f96a..778b25bf4651 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Хороше з’єднання із супутником"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Доступне з’єднання із супутником"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Супутниковий сигнал SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Екстрені виклики або сигнал SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"немає сигналу"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"одна смужка сигналу"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Щоб відкрити, використайте відбиток пальця"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Пройдіть автентифікацію. Для цього торкніться сканера відбитків пальців."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Поточний виклик"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Мобільний трафік"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Підключено"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Тимчасово з’єднано"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Поточний додаток"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Комбінації клавіш"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Налаштуйте комбінації клавіш"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Видалити комбінацію клавіш?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Відновити комбінації клавіш за умовчанням?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Натисніть клавішу, щоб призначити комбінацію клавіш"</string> @@ -1465,6 +1466,10 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Комбінація клавіш уже використовується. Спробуйте іншу клавішу."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Не вдалося встановити комбінацію клавіш."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <!-- no translation found for shortcut_helper_add_shortcut_button_label (7655779534665954910) --> + <skip /> + <!-- no translation found for shortcut_helper_delete_shortcut_button_label (3148773472696137052) --> + <skip /> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Навігація за допомогою клавіатури"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Дізнайтеся більше про комбінації клавіш"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Навігація за допомогою сенсорної панелі"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 63fa93d74ea9..2f3e6f4bcfe8 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"سیٹلائٹ، کنکشن اچھا ہے"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"سیٹلائٹ، کنکشن دستیاب ہے"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"سیٹلائٹ SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"ایمرجنسی کالز یا SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>، <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>۔"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"کوئی سگنل نہیں"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ایک بار"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"کھولنے کے لیے فنگر پرنٹ کا استعمال کریں"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"توثیق مطلوب ہے۔ توثیق کرنے کے لیے فنگر پرنٹ سینسر کو ٹچ کریں۔"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"جاری کال"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"موبائل ڈیٹا"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"منسلک ہے"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"عارضی طور پر منسلک ہے"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"موجودہ ایپ"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"کی بورڈ شارٹ کٹس"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"کی بورڈ شارٹ کٹس کو حسب ضرورت بنائیں"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"شارٹ کٹس کو حسب ضرورت بنائیں"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"شارٹ کٹ ہٹائیں؟"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"ڈیفالٹ پر واپس ری سیٹ کریں؟"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"شارٹ کٹ تفویض کرنے کے لیے کلید کو دبائیں"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"کلیدی مجموعہ پہلے سے استعمال میں ہے۔ دوسری کلید آزمائیں۔"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"شارٹ کٹ سیٹ نہیں کیا جا سکتا۔"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"شارٹ کٹ شامل کریں"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"شارٹ کٹ حذف کریں"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"اپنے کی بورڈ کا استعمال کر کے نیویگیٹ کریں"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"کی بورڈ شارٹ کٹس جانیں"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"اپنے ٹچ پیڈ کا استعمال کر کے نیویگیٹ کریں"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index a20f42d88c7c..23137bd9898c 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Sputnik, aloqa sifati yaxshi"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Sputnik, aloqa mavjud"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Sputnik SOS"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Favqulodda chaqiruvlar yoki SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"signal yoʻq"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"bitta ustun"</string> @@ -871,12 +872,12 @@ <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Kirish bilan bogʻliq tezkor tugmalarni koʻrsatiladi"</string> <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Ilovalarni ochuvchi tezkor tugmalar koʻrsatiladi"</string> <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Joriy ilova uchun tezkor tugmalar koʻrsatiladi"</string> - <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bildirishnomalarni ochish"</string> + <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Bildirishnomalarni koʻrish"</string> <string name="group_system_full_screenshot" msgid="5742204844232667785">"Skrinshot olish"</string> <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Yorliqlarni ochish"</string> <string name="group_system_go_back" msgid="2730322046244918816">"Orqaga"</string> <string name="group_system_access_home_screen" msgid="4130366993484706483">"Bosh ekranni ochish"</string> - <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Oxirgi ilovalarni ochish"</string> + <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Oxirgi ilovalarni koʻrish"</string> <string name="group_system_cycle_forward" msgid="5478663965957647805">"Oxirgi ilovalarni oldinga varaqlash"</string> <string name="group_system_cycle_back" msgid="8194102916946802902">"Oxirgi ilovalarni orqaga varaqlash"</string> <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ilovalar roʻyxatini ochish"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"qurilmani ochish"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Ochish uchun barmoq izidan foydalaning"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Haqiqiylikni tekshirish talab etiladi. Autentifikatsiya uchun barmoq izi skaneriga tegining."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Joriy chaqiruv"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Mobil internet"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ulangan"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Vaqtincha ulangan"</string> @@ -1437,7 +1437,8 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Joriy ilova"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Tezkor tugmalar"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tezkor tugmalarni moslash"</string> + <!-- no translation found for shortcut_helper_customize_mode_title (8327297960035006036) --> + <skip /> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Tezkor tugma olib tashlansinmi?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Asliga qaytarilsinmi?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Tezkor tugma sozlash uchun tugmani bosing"</string> @@ -1465,6 +1466,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Bu tugmalar birikmasi band. Boshqasini ishlating."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Buyruq sozlanmadi."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Yorliq yaratish"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Yorliqni oʻchirish"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Klaviatura yordamida kezing"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tezkor tugmalar haqida"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Sensorli panel yordamida kezing"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 2a8fa4c9cc7b..3b4b132698f3 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Kết nối vệ tinh tốt"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Hiện có kết nối vệ tinh"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Liên lạc khẩn cấp qua vệ tinh"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Cuộc gọi khẩn cấp hoặc SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"không có tín hiệu"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"1 vạch"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"truy cập thiết bị"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Dùng vân tay để mở"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Bạn cần phải xác thực. Hãy chạm vào cảm biến vân tay để xác thực."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Cuộc gọi đang diễn ra"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Dữ liệu di động"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Đã kết nối"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Tạm thời có kết nối"</string> @@ -1433,11 +1433,11 @@ <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Đa nhiệm"</string> <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Chia đôi màn hình"</string> <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Phương thức nhập"</string> - <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lối tắt ứng dụng"</string> + <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Phím tắt cho ứng dụng"</string> <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"Ứng dụng hiện tại"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Phím tắt"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Tuỳ chỉnh phím tắt"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Tuỳ chỉnh phím tắt"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Xoá phím tắt?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Đặt lại về phím tắt mặc định?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Nhấn phím để chỉ định phím tắt"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Tổ hợp phím đã được sử dụng. Hãy thử một phím khác."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Không đặt được lối tắt."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Thêm phím tắt"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Xoá phím tắt"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Di chuyển bằng bàn phím"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Tìm hiểu về phím tắt"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Di chuyển bằng bàn di chuột"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 8f0b2f11da93..e66048e8022a 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"卫星,连接质量良好"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"卫星,可连接"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"卫星紧急呼救"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"紧急呼叫或紧急求救"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>。"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"无信号"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"信号强度为一格"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"进入设备"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指纹即可打开"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要进行身份验证。请轻触指纹传感器以验证身份。"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"正在通话"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"移动数据网络"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"已连接"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暂时连接"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"当前应用"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"键盘快捷键"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自定义键盘快捷键"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"自定义快捷方式"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快捷键吗?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重置为默认快捷键吗?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"按下按键即可指定快捷键"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"按键组合已被使用,请尝试使用其他按键。"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"无法设置快捷方式。"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"添加快捷方式"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"删除快捷方式"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用键盘导航"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"了解键盘快捷键"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用触控板导航"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index afae659eb972..f9631f267948 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線質素好"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可以連線"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"緊急衛星連接"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急電話或 SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>。"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"無訊號"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"一格"</string> @@ -877,8 +878,8 @@ <string name="group_system_go_back" msgid="2730322046244918816">"返回"</string> <string name="group_system_access_home_screen" msgid="4130366993484706483">"前往主畫面"</string> <string name="group_system_overview_open_apps" msgid="5659958952937994104">"查看最近使用的應用程式"</string> - <string name="group_system_cycle_forward" msgid="5478663965957647805">"輪流切換最近使用的應用程式 (向前)"</string> - <string name="group_system_cycle_back" msgid="8194102916946802902">"輪流切換最近使用的應用程式 (向後)"</string> + <string name="group_system_cycle_forward" msgid="5478663965957647805">"順序查看最近使用的應用程式"</string> + <string name="group_system_cycle_back" msgid="8194102916946802902">"倒序查看最近使用的應用程式"</string> <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"開啟應用程式清單"</string> <string name="group_system_access_system_settings" msgid="8731721963449070017">"開啟設定"</string> <string name="group_system_access_google_assistant" msgid="7210074957915968110">"開啟「Google 助理」"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要驗證。掂一下指紋感應器就可以驗證。"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"流動數據"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"已連線"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暫時連線"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"自訂快速鍵"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快速鍵嗎?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重設至預設捷徑嗎?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"按鍵即可指派快速鍵"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"此按鍵組合已在使用,請改用其他按鍵。"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"無法設定快速鍵。"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"新增捷徑"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"刪除捷徑"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤導覽"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"瞭解鍵盤快速鍵"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板導覽"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index f52e906add3e..4394dd9a0bd7 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -759,7 +759,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"衛星,連線品質良好"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"衛星,可連線"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"緊急衛星連線"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"緊急電話或緊急求救"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>,<xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>。"</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"沒有訊號"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"訊號強度一格"</string> @@ -1289,8 +1290,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"使用指紋即可開啟"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"需要驗證。輕觸指紋感應器即可進行驗證。"</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"通話中"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"行動數據"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"已連線"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暫時建立連線"</string> @@ -1437,7 +1437,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"目前的應用程式"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"鍵盤快速鍵"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"自訂鍵盤快速鍵"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"自訂快速鍵"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"要移除快速鍵嗎?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"要重設為預設值嗎?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"按下按鍵即可指派快速鍵"</string> @@ -1465,6 +1465,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"按鍵組合重複,請改用其他按鍵。"</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"無法設定捷徑。"</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"新增快速鍵"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"刪除快速鍵"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"使用鍵盤操作"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"學習鍵盤快速鍵"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"使用觸控板操作"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index a63167ed8ac2..f7f4bcfcdc83 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -761,7 +761,8 @@ <string name="accessibility_status_bar_satellite_good_connection" msgid="308079391708578704">"Isethelayithi, uxhumano oluhle"</string> <string name="accessibility_status_bar_satellite_available" msgid="6514855015496916829">"Isethelayithi, uxhumano luyatholakala"</string> <string name="satellite_connected_carrier_text" msgid="118524195198532589">"Isethelayithi yokuxhumana ngezimo eziphuthumayo"</string> - <string name="satellite_emergency_only_carrier_text" msgid="828510231597991206">"Ikholi ephuthumayo noma i-SOS"</string> + <!-- no translation found for satellite_emergency_only_carrier_text (9103913890116841786) --> + <skip /> <string name="accessibility_phone_string_format" msgid="7798841417881811812">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="SIGNAL_STRENGTH_DESCRIPTION">%2$s</xliff:g>."</string> <string name="accessibility_no_signal" msgid="7052827511409250167">"ayikho isignali"</string> <string name="accessibility_one_bar" msgid="5342012847647834506">"ibha eyodwa"</string> @@ -1291,8 +1292,7 @@ <string name="accessibility_enter_hint" msgid="2617864063504824834">"faka idivayisi"</string> <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Sebenzisa izigxivizo zeminwe ukuvula"</string> <string name="accessibility_fingerprint_bouncer" msgid="7189102492498735519">"Ukufakazela ubuqiniso budingekile. Thinta inzwa yezigxivizo zeminwe ukuze uqinisekise."</string> - <!-- no translation found for ongoing_call_content_description (6394763878322348560) --> - <skip /> + <string name="ongoing_call_content_description" msgid="6394763878322348560">"Ikholi eqhubekayo"</string> <string name="mobile_data_settings_title" msgid="3955246641380064901">"Idatha yeselula"</string> <string name="mobile_data_connection_active" msgid="944490013299018227">"Ixhunyiwe"</string> <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Ixhume okwesikhashana"</string> @@ -1439,7 +1439,7 @@ <string name="shortcut_helper_category_current_app_shortcuts" msgid="4017840565974573628">"I-App yamanje"</string> <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string> <string name="shortcut_helper_title" msgid="8567500639300970049">"Izinqamuleli zekhibhodi"</string> - <string name="shortcut_helper_customize_mode_title" msgid="1467657117101096033">"Hlela izinqamuleli zekhibhodi ngendlela oyifisayo"</string> + <string name="shortcut_helper_customize_mode_title" msgid="8327297960035006036">"Qamba ngokwabahlinzekelwayo izinqamuleli"</string> <string name="shortcut_customize_mode_remove_shortcut_dialog_title" msgid="7106420484940737208">"Susa isinqamuleli?"</string> <string name="shortcut_customize_mode_reset_shortcut_dialog_title" msgid="8131184731313717780">"Setha kabusha ubuyele kokuzenzakalelayo?"</string> <string name="shortcut_customize_mode_add_shortcut_description" msgid="6866025005347407696">"Cindezela ukhiye ukuze unikeze isinqamuleli"</string> @@ -1467,6 +1467,8 @@ <string name="shortcut_customizer_key_combination_in_use_error_message" msgid="7693234470526626327">"Inhlanganisela yokhiye isiyasetshenziswa kakade. Zama omunye ukhiye."</string> <string name="shortcut_customizer_generic_error_message" msgid="3128454624049722741">"Isinqamuleli asikwazi ukusethwa."</string> <string name="shortcut_helper_plus_symbol" msgid="4534843157353732011">"+"</string> + <string name="shortcut_helper_add_shortcut_button_label" msgid="7655779534665954910">"Faka isinqamuleli"</string> + <string name="shortcut_helper_delete_shortcut_button_label" msgid="3148773472696137052">"Sula isinqamuleli"</string> <string name="launch_keyboard_tutorial_notification_title" msgid="8849933155160522519">"Funa usebenzisa ikhibhodi yakho"</string> <string name="launch_keyboard_tutorial_notification_content" msgid="2880339951512757918">"Funda izinqamuleli zamakhibhodi"</string> <string name="launch_touchpad_tutorial_notification_title" msgid="2243780062772196901">"Funa usebenzisa iphedi yokuthinta"</string> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 2ffa3d19e161..f9904e336f24 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -254,9 +254,6 @@ <!-- Reference width used when validating notification layouts --> <dimen name="notification_validation_reference_width">320dp</dimen> - <!-- Increased height of a small notification in the status bar --> - <dimen name="notification_min_height_increased">146dp</dimen> - <!-- Height of a small notification in the status bar which was used before android N --> <dimen name="notification_min_height_legacy">64dp</dimen> @@ -281,9 +278,6 @@ <!-- Height of a heads up notification in the status bar --> <dimen name="notification_max_heads_up_height">136dp</dimen> - <!-- Height of a heads up notification in the status bar --> - <dimen name="notification_max_heads_up_height_increased">188dp</dimen> - <!-- Side padding on the side of notifications --> <dimen name="notification_side_paddings">16dp</dimen> @@ -1128,6 +1122,7 @@ <dimen name="smart_reply_button_corner_radius">8dp</dimen> <dimen name="smart_action_button_icon_size">18dp</dimen> <dimen name="smart_action_button_icon_padding">8dp</dimen> + <dimen name="smart_action_button_outline_stroke_width">2dp</dimen> <!-- A reasonable upper bound for the height of the smart reply button. The measuring code needs to start with a guess for the maximum size. Currently two-line smart reply buttons diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e785af8e36c9..414d3f1d17d5 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2250,8 +2250,6 @@ <string name="keyboard_shortcut_group_system_notifications">Notifications</string> <!-- User visible title for the keyboard shortcut that triggers the keyboard shortcuts helper. --> <string name="keyboard_shortcut_group_system_shortcuts_helper">Keyboard Shortcuts</string> - <!-- User visible title for the keyboard shortcut that switches to the next hardware keyboard layout. --> - <string name="keyboard_shortcut_group_system_switch_input">Switch keyboard layout</string> <!-- User visible string that joins different shortcuts in a list, e.g. shortcut1 "or" shortcut2 "or" ... --> <string name="keyboard_shortcut_join">or</string> @@ -3956,6 +3954,8 @@ <string name="touchpad_tutorial_home_gesture_button">Go home</string> <!-- Label for button opening tutorial for "view recent apps" gesture on touchpad [CHAR LIMIT=NONE] --> <string name="touchpad_tutorial_recent_apps_gesture_button">View recent apps</string> + <!-- Label for button opening tutorial for "switch apps" gesture on touchpad [CHAR LIMIT=NONE] --> + <string name="touchpad_tutorial_switch_apps_gesture_button">Switch apps</string> <!-- Label for button finishing touchpad tutorial [CHAR LIMIT=NONE] --> <string name="touchpad_tutorial_done_button">Done</string> <!-- Screen title after gesture was not done correctly [CHAR LIMIT=NONE] --> @@ -3993,6 +3993,17 @@ <string name="touchpad_recent_apps_gesture_success_body">You completed the view recent apps gesture.</string> <!-- Text shown to the user after recent gesture was not done correctly [CHAR LIMIT=NONE] --> <string name="touchpad_recent_gesture_error_body">To view recent apps, swipe up and hold using three fingers on your touchpad</string> + <!-- SWITCH APPS GESTURE --> + <!-- Touchpad switch apps gesture action name in tutorial [CHAR LIMIT=NONE] --> + <string name="touchpad_switch_apps_gesture_action_title">Switch apps</string> + <!-- Touchpad switch apps gesture guidance in gestures tutorial [CHAR LIMIT=NONE] --> + <string name="touchpad_switch_apps_gesture_guidance">Swipe left or right using four fingers on your touchpad</string> + <!-- Screen title after switch apps gesture was done successfully [CHAR LIMIT=NONE] --> + <string name="touchpad_switch_apps_gesture_success_title">Great job!</string> + <!-- Text shown to the user after they complete switch apps gesture tutorial [CHAR LIMIT=NONE] --> + <string name="touchpad_switch_apps_gesture_success_body">You completed the switch apps gesture.</string> + <!-- Text shown to the user after switch gesture was not done correctly [CHAR LIMIT=NONE] --> + <string name="touchpad_switch_gesture_error_body">Swipe left or right using four fingers on your touchpad to switch apps</string> <!-- KEYBOARD TUTORIAL--> <!-- Action key tutorial title [CHAR LIMIT=NONE] --> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java index 1c5da827eeb3..3d2ce4229bd5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java @@ -27,9 +27,10 @@ public interface PluginEnabler { int DISABLED_INVALID_VERSION = 2; int DISABLED_FROM_EXPLICIT_CRASH = 3; int DISABLED_FROM_SYSTEM_CRASH = 4; + int DISABLED_UNKNOWN = 100; @IntDef({ENABLED, DISABLED_MANUALLY, DISABLED_INVALID_VERSION, DISABLED_FROM_EXPLICIT_CRASH, - DISABLED_FROM_SYSTEM_CRASH}) + DISABLED_FROM_SYSTEM_CRASH, DISABLED_UNKNOWN}) @interface DisableReason { } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl index 83ca496dbef2..2b71c87bfa27 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl @@ -19,10 +19,11 @@ package com.android.systemui.shared.recents; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; +import android.os.IRemoteCallback; import android.view.MotionEvent; import com.android.systemui.shared.recents.ISystemUiProxy; -// Next ID: 34 +// Next ID: 36 oneway interface IOverviewProxy { void onActiveNavBarRegionChanges(in Region activeRegion) = 11; @@ -137,4 +138,10 @@ oneway interface IOverviewProxy { * Sent when {@link TaskbarDelegate#appTransitionPending} is called. */ void appTransitionPending(boolean pending) = 34; + + /** + * Sent right after OverviewProxy calls unbindService() on the TouchInteractionService. + * TouchInteractionService is expected to send the reply once it has finished cleaning up. + */ + void onUnbind(IRemoteCallback reply) = 35; } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java index 51892aac606a..ff6bcdb150f8 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java @@ -19,6 +19,7 @@ package com.android.systemui.shared.system; import android.graphics.Rect; import android.os.Bundle; import android.view.RemoteAnimationTarget; +import android.window.TransitionInfo; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -30,7 +31,7 @@ public interface RecentsAnimationListener { */ void onAnimationStart(RecentsAnimationControllerCompat controller, RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras); + Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras, TransitionInfo info); /** * Called when the animation into Recents was canceled. This call is made on the binder thread. diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java index caf043a1b1be..b2f3df60c82b 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java @@ -200,7 +200,15 @@ public class FullscreenMagnificationController implements ComponentCallbacks { valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation) { - mHandler.post(() -> setState(ENABLED)); + // This could be called when the animation ends or is canceled. Therefore, we need + // to check the state of fullscreen magnification for the following actions. We only + // update the state to ENABLED when the previous state is ENABLING which implies + // fullscreen magnification is experiencing an ongoing create border process. + mHandler.post(() -> { + if (getState() == ENABLING) { + setState(ENABLED); + } + }); }}); return valueAnimator; } @@ -221,7 +229,14 @@ public class FullscreenMagnificationController implements ComponentCallbacks { valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(@NonNull Animator animation) { - mHandler.post(() -> cleanUpBorder()); + // This could be called when the animation ends or is canceled. Therefore, we need + // to check the state of fullscreen magnification for the following actions. Border + // cleanup should only happens after a removal process. + mHandler.post(() -> { + if (getState() == DISABLING) { + cleanUpBorder(); + } + }); }}); return valueAnimator; } @@ -250,6 +265,8 @@ public class FullscreenMagnificationController implements ComponentCallbacks { // If there is an ongoing disable process or it is already disabled, return return; } + // The state should be updated as early as possible so others could check + // the ongoing process. setState(DISABLING); mShowHideBorderAnimator = createHideTargetAnimator(mFullscreenBorder); mShowHideBorderAnimator.start(); @@ -297,10 +314,13 @@ public class FullscreenMagnificationController implements ComponentCallbacks { // If there is an ongoing enable process or it is already enabled, return return; } + // The state should be updated as early as possible so others could check + // the ongoing process. + setState(ENABLING); + if (mShowHideBorderAnimator != null) { mShowHideBorderAnimator.cancel(); } - setState(ENABLING); onConfigurationChanged(mContext.getResources().getConfiguration()); mContext.registerComponentCallbacks(this); diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt index 6635d8b06a5d..a061d38d0c18 100644 --- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt @@ -215,7 +215,8 @@ constructor( override val isAutoConfirmFeatureEnabled: StateFlow<Boolean> = refreshingFlow( - initialValue = false, + initialValue = + lockPatternUtils.isAutoPinConfirmEnabled(userRepository.getSelectedUserInfo().id), getFreshValue = lockPatternUtils::isAutoPinConfirmEnabled, ) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt index 68ec0f2d57ef..39f55803bb73 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FingerprintPropertyRepository.kt @@ -68,7 +68,7 @@ interface FingerprintPropertyRepository { val sensorType: StateFlow<FingerprintSensorType> /** The sensor location relative to each physical display. */ - val sensorLocations: Flow<Map<String, SensorLocationInternal>> + val sensorLocations: StateFlow<Map<String, SensorLocationInternal>> } @SysUISingleton @@ -128,12 +128,14 @@ constructor( initialValue = props.value.sensorType.toSensorType(), ) - override val sensorLocations: Flow<Map<String, SensorLocationInternal>> = - props.map { - it.allLocations.associateBy { sensorLocationInternal -> - sensorLocationInternal.displayId - } - } + override val sensorLocations: StateFlow<Map<String, SensorLocationInternal>> = + props + .map { props -> props.allLocations.associateBy { it.displayId } } + .stateIn( + applicationScope, + started = SharingStarted.Eagerly, + initialValue = props.value.allLocations.associateBy { it.displayId }, + ) override val propertiesInitialized: Flow<Boolean> = combine( diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt index d9ed9ca1f07b..ae855d19715e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt @@ -20,11 +20,11 @@ import android.content.Context import android.graphics.Rect import android.hardware.biometrics.SensorLocationInternal import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository -import com.android.systemui.biometrics.shared.model.SensorLocation import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.shared.customization.data.SensorLocation import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow @@ -42,8 +42,8 @@ class FingerprintPropertyInteractor constructor( @Application private val applicationScope: CoroutineScope, @Application private val context: Context, - repository: FingerprintPropertyRepository, - @Main configurationInteractor: ConfigurationInteractor, + private val repository: FingerprintPropertyRepository, + @Main private val configurationInteractor: ConfigurationInteractor, displayStateInteractor: DisplayStateInteractor, udfpsOverlayInteractor: UdfpsOverlayInteractor, ) { @@ -61,11 +61,16 @@ constructor( * Devices with multiple physical displays use unique display ids to determine which sensor is * on the active physical display. This value represents a unique physical display id. */ - private val uniqueDisplayId: Flow<String> = + private val uniqueDisplayId: StateFlow<String> = displayStateInteractor.displayChanges - .map { context.display?.uniqueId } + .map { context.display.uniqueId } .filterNotNull() .distinctUntilChanged() + .stateIn( + scope = applicationScope, + started = SharingStarted.Eagerly, + initialValue = EMPTY_DISPLAY_ID, + ) /** * Sensor location for the: @@ -73,13 +78,15 @@ constructor( * - device's natural screen resolution * - device's natural orientation */ - private val unscaledSensorLocation: Flow<SensorLocationInternal> = - combine(repository.sensorLocations, uniqueDisplayId) { locations, displayId -> + private val unscaledSensorLocation: StateFlow<SensorLocationInternal> = + combineStates(repository.sensorLocations, uniqueDisplayId, applicationScope) { + locations, + displayId -> // Devices without multiple physical displays do not use the display id as the key; // instead, the key is an empty string. locations.getOrDefault( displayId, - locations.getOrDefault("", SensorLocationInternal.DEFAULT), + locations.getOrDefault(EMPTY_DISPLAY_ID, SensorLocationInternal.DEFAULT), ) } @@ -89,18 +96,18 @@ constructor( * - current screen resolution * - device's natural orientation */ - val sensorLocation: Flow<SensorLocation> = - combine(unscaledSensorLocation, configurationInteractor.scaleForResolution) { + val sensorLocation: StateFlow<SensorLocation> = + combineStates( unscaledSensorLocation, - scale -> - val sensorLocation = - SensorLocation( - naturalCenterX = unscaledSensorLocation.sensorLocationX, - naturalCenterY = unscaledSensorLocation.sensorLocationY, - naturalRadius = unscaledSensorLocation.sensorRadius, - scale = scale, - ) - sensorLocation + configurationInteractor.scaleForResolution, + applicationScope, + ) { unscaledSensorLocation, scale -> + SensorLocation( + naturalCenterX = unscaledSensorLocation.sensorLocationX, + naturalCenterY = unscaledSensorLocation.sensorLocationY, + naturalRadius = unscaledSensorLocation.sensorRadius, + scale = scale, + ) } /** @@ -111,4 +118,19 @@ constructor( */ val udfpsSensorBounds: Flow<Rect> = udfpsOverlayInteractor.udfpsOverlayParams.map { it.sensorBounds }.distinctUntilChanged() + + companion object { + + private const val EMPTY_DISPLAY_ID = "" + + /** Combine two state flows to another state flow. */ + private fun <T1, T2, R> combineStates( + flow1: StateFlow<T1>, + flow2: StateFlow<T2>, + scope: CoroutineScope, + transform: (T1, T2) -> R, + ): StateFlow<R> = + combine(flow1, flow2) { v1, v2 -> transform(v1, v2) } + .stateIn(scope, SharingStarted.Eagerly, transform(flow1.value, flow2.value)) + } } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt index c05dcd5cea83..c59c6816a350 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/composable/BouncerContainer.kt @@ -41,13 +41,12 @@ fun BouncerContainer( Box { Canvas(Modifier.fillMaxSize()) { drawRect(color = backgroundColor) } - // Separate the bouncer content into a reusable composable that - // doesn't have any SceneScope - // dependencies + // Separate the bouncer content into a reusable composable that doesn't have any + // ContentScope dependencies BouncerContent( bouncerViewModel, dialogFactory, - Modifier.sysuiResTag(Bouncer.TestTags.Root).fillMaxSize() + Modifier.sysuiResTag(Bouncer.TestTags.Root).fillMaxSize(), ) } } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt index 5baec1e025e8..73aaf7f8e460 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt @@ -29,11 +29,11 @@ import android.view.KeyEvent.isConfirmKey import android.view.View import androidx.compose.ui.input.key.KeyEvent import androidx.compose.ui.input.key.KeyEventType +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.keyguard.PinShapeAdapter import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor -import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags import com.android.systemui.bouncer.ui.helper.BouncerHapticPlayer import com.android.systemui.res.R import dagger.assisted.Assisted @@ -50,7 +50,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.receiveAsFlow -import com.android.app.tracing.coroutines.launchTraced as launch /** Holds UI state and handles user input for the PIN code bouncer UI. */ class PinBouncerViewModel @@ -289,11 +288,10 @@ constructor( * feedback on the view. */ fun onDigitButtonDown(view: View?) { - if (ComposeBouncerFlags.isOnlyComposeBouncerEnabled()) { - // Current PIN bouncer informs FalsingInteractor#avoidGesture() upon every Pin button - // touch. - super.onDown() - } + // This ends up calling FalsingInteractor#avoidGesture() each time a PIN button is touched. + // It helps make sure that legitimate touch in the PIN bouncer isn't treated as false touch. + super.onDown() + if (bouncerHapticPlayer?.isEnabled == true) { bouncerHapticPlayer.playNumpadKeyFeedback() } else { diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt index b79538aac3e6..60cdccdeaadd 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCoreStartable.kt @@ -21,8 +21,9 @@ import javax.inject.Inject /** Initializes classes related to falsing. */ @SysUISingleton -class FalsingCoreStartable @Inject constructor(val falsingCollector: FalsingCollector) : - CoreStartable { +class FalsingCoreStartable +@Inject +constructor(@FalsingCollectorActual val falsingCollector: FalsingCollector) : CoreStartable { override fun start() { falsingCollector.init() } diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt index 747a2a9bd887..7fcdd9596049 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/data/repository/ConfigurationRepository.kt @@ -52,7 +52,7 @@ interface ConfigurationRepository { /** Called whenever the configuration has changed. */ val onConfigurationChange: Flow<Unit> - val scaleForResolution: Flow<Float> + val scaleForResolution: StateFlow<Float> val configurationValues: Flow<Configuration> diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt index 97a23e1a5010..4d39b033cd7b 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/common/ui/domain/interactor/ConfigurationInteractor.kt @@ -23,6 +23,7 @@ import android.view.Surface import com.android.systemui.common.ui.data.repository.ConfigurationRepository import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -60,7 +61,7 @@ interface ConfigurationInteractor { val configurationValues: Flow<Configuration> /** Emits the current resolution scaling factor */ - val scaleForResolution: Flow<Float> + val scaleForResolution: StateFlow<Float> /** Given [resourceId], emit the dimension pixel size on config change */ fun dimensionPixelSize(resourceId: Int): Flow<Int> @@ -121,5 +122,5 @@ class ConfigurationInteractorImpl(private val repository: ConfigurationRepositor override val configurationValues: Flow<Configuration> = repository.configurationValues - override val scaleForResolution: Flow<Float> = repository.scaleForResolution + override val scaleForResolution: StateFlow<Float> = repository.scaleForResolution } diff --git a/packages/SystemUI/src/com/android/systemui/communal/DevicePosturingCommandListener.kt b/packages/SystemUI/src/com/android/systemui/communal/DevicePosturingCommandListener.kt new file mode 100644 index 000000000000..c7b7050340a0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/DevicePosturingCommandListener.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025 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 + +import android.annotation.SuppressLint +import android.app.DreamManager +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.commandline.Command +import com.android.systemui.statusbar.commandline.CommandRegistry +import java.io.PrintWriter +import javax.inject.Inject + +@SysUISingleton +class DevicePosturingCommandListener +@Inject +constructor(private val commandRegistry: CommandRegistry, private val dreamManager: DreamManager) : + CoreStartable { + private val command = DevicePosturingCommand() + + override fun start() { + commandRegistry.registerCommand(COMMAND_ROOT) { command } + } + + internal inner class DevicePosturingCommand : Command { + @SuppressLint("MissingPermission") + override fun execute(pw: PrintWriter, args: List<String>) { + val arg = args.getOrNull(0) + if (arg == null || arg.lowercase() == "help") { + help(pw) + return + } + + when (arg.lowercase()) { + "true" -> dreamManager.setDevicePostured(true) + "false" -> dreamManager.setDevicePostured(false) + else -> { + pw.println("Invalid argument!") + help(pw) + } + } + } + + override fun help(pw: PrintWriter) { + pw.println("Usage: $ adb shell cmd statusbar device-postured <true|false>") + } + } + + private companion object { + const val COMMAND_ROOT = "device-postured" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt index 2d19b026489c..e3443227685f 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalStartableModule.kt @@ -22,6 +22,7 @@ import com.android.systemui.communal.CommunalDreamStartable import com.android.systemui.communal.CommunalMetricsStartable import com.android.systemui.communal.CommunalOngoingContentStartable import com.android.systemui.communal.CommunalSceneStartable +import com.android.systemui.communal.DevicePosturingCommandListener import com.android.systemui.communal.log.CommunalLoggerStartable import com.android.systemui.communal.widgets.CommunalAppWidgetHostStartable import com.android.systemui.dagger.qualifiers.PerUser @@ -67,4 +68,9 @@ interface CommunalStartableModule { @IntoMap @ClassKey(CommunalMetricsStartable::class) fun bindCommunalMetricsStartable(impl: CommunalMetricsStartable): CoreStartable + + @Binds + @IntoMap + @ClassKey(DevicePosturingCommandListener::class) + fun bindDevicePosturingCommandListener(impl: DevicePosturingCommandListener): CoreStartable } diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt index 6c6d730819f3..911327a0bd18 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryUdfpsInteractor.kt @@ -17,10 +17,10 @@ package com.android.systemui.deviceentry.domain.interactor import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor -import com.android.systemui.biometrics.shared.model.SensorLocation import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository +import com.android.systemui.shared.customization.data.SensorLocation import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt index 7d684cab39f7..5e3b2ae0b59f 100644 --- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt @@ -132,8 +132,6 @@ constructor( DeviceEntryRestrictionReason.UnattendedUpdate authFlags.isPrimaryAuthRequiredAfterTimeout -> DeviceEntryRestrictionReason.SecurityTimeout - authFlags.isPrimaryAuthRequiredAfterLockout -> - DeviceEntryRestrictionReason.BouncerLockedOut isFingerprintLockedOut -> DeviceEntryRestrictionReason.StrongBiometricsLockedOut isFaceLockedOut && faceAuthInteractor.isFaceAuthStrong() -> @@ -376,8 +374,7 @@ constructor( private val interactor: DeviceUnlockedInteractor, ) : CoreStartable { override fun start() { - if (!SceneContainerFlag.isEnabled) - return + if (!SceneContainerFlag.isEnabled) return applicationScope.launch { interactor.activate() } } diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt index 2412ad442e66..9596a540b63b 100644 --- a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt @@ -77,8 +77,6 @@ interface ContextualEducationRepository { transform: (EduDeviceConnectionTime) -> EduDeviceConnectionTime ) - suspend fun clear() - val keyboardShortcutTriggered: Flow<GestureType> } @@ -280,8 +278,4 @@ constructor( preferences.remove(key) } } - - override suspend fun clear() { - datastore.filterNotNull().first().edit { it.clear() } - } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt index 7a72732ea6bf..18cabad6b2d5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/CustomizationProvider.kt @@ -33,6 +33,7 @@ import android.util.Log import com.android.app.tracing.coroutines.runBlockingTraced as runBlocking import com.android.systemui.SystemUIAppComponentFactoryBase import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback +import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor import com.android.systemui.keyguard.ui.preview.KeyguardRemotePreviewManager @@ -46,6 +47,7 @@ class CustomizationProvider : @Inject lateinit var interactor: KeyguardQuickAffordanceInteractor @Inject lateinit var shadeModeInteractor: ShadeModeInteractor + @Inject lateinit var fingerprintPropertyInteractor: FingerprintPropertyInteractor @Inject lateinit var previewManager: KeyguardRemotePreviewManager @Inject @Main lateinit var mainDispatcher: CoroutineDispatcher @@ -345,6 +347,14 @@ class CustomizationProvider : } private fun queryRuntimeValues(): Cursor { + // If not UDFPS, the udfpsLocation will be null + val udfpsLocation = + if (fingerprintPropertyInteractor.isUdfps.value) { + fingerprintPropertyInteractor.sensorLocation.value + } else { + null + } + return MatrixCursor( arrayOf( Contract.RuntimeValuesTable.Columns.NAME, @@ -358,6 +368,9 @@ class CustomizationProvider : if (shadeModeInteractor.isShadeLayoutWide.value) 1 else 0, ) ) + addRow( + arrayOf(Contract.RuntimeValuesTable.KEY_UDFPS_LOCATION, udfpsLocation?.encode()) + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 647362873015..5baef915ea01 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -3492,7 +3492,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, public void showSurfaceBehindKeyguard() { mSurfaceBehindRemoteAnimationRequested = true; - if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { + if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS && !KeyguardWmStateRefactor.isEnabled()) { startKeyguardTransition(false /* keyguardShowing */, false /* aodShowing */); return; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS index 208a17c0a220..ebe603b7428c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS @@ -2,6 +2,8 @@ set noparent # Bug component: 78010 +include /services/core/java/com/android/server/biometrics/OWNERS + amiko@google.com beverlyt@google.com bhinegardner@google.com diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt index a74384f61469..58692746d1e0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerLockscreenVisibilityManager.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard import android.app.IActivityTaskManager +import android.os.RemoteException import android.util.Log import android.view.IRemoteAnimationFinishedCallback import android.view.RemoteAnimationTarget @@ -174,25 +175,24 @@ constructor( if (!isKeyguardGoingAway) { // Since WM triggered this, we're likely not transitioning to GONE yet. See if we can // start that transition. - val startedDismiss = - keyguardDismissTransitionInteractor.startDismissKeyguardTransition( - reason = "Going away remote animation started" - ) - - if (!startedDismiss) { - // If the transition wasn't started, we're already GONE. This can happen with timing - // issues, where the remote animation took a long time to start, and something else - // caused us to unlock in the meantime. Since we're already GONE, simply end the - // remote animatiom immediately. - Log.d( - TAG, - "onKeyguardGoingAwayRemoteAnimationStart: " + - "Dismiss transition was not started; we're already GONE. " + - "Ending remote animation.", - ) - finishedCallback.onAnimationFinished() - return - } + keyguardDismissTransitionInteractor.startDismissKeyguardTransition( + reason = "Going away remote animation started", + onAlreadyGone = { + // Called if we're already GONE by the time the dismiss transition would have + // started. This can happen due to timing issues, where the remote animation + // took a long time to start, and something else caused us to unlock in the + // meantime. Since we're already GONE, simply end the remote animation + // immediately. + Log.d( + TAG, + "onKeyguardGoingAwayRemoteAnimationStart: " + + "Dismiss transition was not started; we're already GONE. " + + "Ending remote animation.", + ) + finishedCallback.onAnimationFinished() + isKeyguardGoingAway = false + }, + ) isKeyguardGoingAway = true } @@ -266,7 +266,11 @@ constructor( if (enableNewKeyguardShellTransitions) { startKeyguardTransition(lockscreenShowing, aodVisible) } else { - activityTaskManagerService.setLockScreenShown(lockscreenShowing, aodVisible) + try { + activityTaskManagerService.setLockScreenShown(lockscreenShowing, aodVisible) + } catch (e: RemoteException) { + Log.e(TAG, "Remote exception", e) + } } this.isLockscreenShowing = lockscreenShowing this.isAodVisible = aodVisible diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/PrimaryBouncerTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/PrimaryBouncerTransitionModule.kt index cc070b66917b..d3e2560d6a21 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/PrimaryBouncerTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/PrimaryBouncerTransitionModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.keyguard.dagger import android.content.res.Resources +import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.ui.transitions.BlurConfig @@ -34,7 +35,6 @@ import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransition import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToLockscreenTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToOccludedTransitionViewModel import com.android.systemui.res.R -import com.android.systemui.window.flag.WindowBlurFlag import dagger.Binds import dagger.Module import dagger.Provides @@ -56,7 +56,7 @@ interface PrimaryBouncerTransitionModule { fun provideBlurConfig(@Main resources: Resources): BlurConfig { val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius) val maxBlurRadius = - if (WindowBlurFlag.isEnabled) { + if (Flags.notificationShadeBlur() || Flags.bouncerUiRevamp()) { resources.getDimensionPixelSize(R.dimen.max_shade_window_blur_radius) } else { resources.getDimensionPixelSize(R.dimen.max_window_blur_radius) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt index 1b8baf657948..f11ebee46659 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt @@ -26,8 +26,8 @@ import android.provider.Settings.Secure.ZEN_DURATION_FOREVER import android.provider.Settings.Secure.ZEN_DURATION_PROMPT import android.service.notification.ZenModeConfig import android.util.Log -import com.android.settingslib.notification.modes.EnableZenModeDialog -import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger +import com.android.settingslib.notification.modes.EnableDndDialogFactory +import com.android.settingslib.notification.modes.EnableDndDialogMetricsLogger import com.android.systemui.animation.Expandable import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow @@ -60,8 +60,7 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn @SysUISingleton -class DoNotDisturbQuickAffordanceConfig -constructor( +class DoNotDisturbQuickAffordanceConfig( private val context: Context, private val controller: ZenModeController, private val interactor: ZenModeInteractor, @@ -70,7 +69,7 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, @Background private val backgroundScope: CoroutineScope, private val testConditionId: Uri?, - testDialog: EnableZenModeDialog?, + testDialogFactory: EnableDndDialogFactory?, ) : KeyguardQuickAffordanceConfig { @Inject @@ -118,13 +117,13 @@ constructor( ) .id - private val dialog: EnableZenModeDialog by lazy { - testDialog - ?: EnableZenModeDialog( + private val dialogFactory: EnableDndDialogFactory by lazy { + testDialogFactory + ?: EnableDndDialogFactory( context, R.style.Theme_SystemUI_Dialog, true, /* cancelIsNeutral */ - ZenModeDialogMetricsLogger(context), + EnableDndDialogMetricsLogger(context), ) } @@ -224,7 +223,7 @@ constructor( if (interactor.shouldAskForZenDuration(dnd)) { // NOTE: The dialog handles turning on the mode itself. return KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog( - dialog.createDialog(), + dialogFactory.createDialog(), expandable, ) } else { @@ -243,7 +242,7 @@ constructor( settingsValue == ZEN_DURATION_PROMPT -> KeyguardQuickAffordanceConfig.OnTriggeredResult.ShowDialog( - dialog.createDialog(), + dialogFactory.createDialog(), expandable, ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt index 089e5dc42df3..c0a486c005ab 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt @@ -16,23 +16,31 @@ package com.android.systemui.keyguard.domain.interactor +import android.animation.ValueAnimator import android.util.Log import com.android.systemui.Flags.transitionRaceCondition import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER 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.OCCLUDED 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.TransitionModeOnCanceled import com.android.systemui.scene.shared.flag.SceneContainerFlag import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch @SysUISingleton class KeyguardDismissTransitionInteractor @Inject constructor( + @Background private val scope: CoroutineScope, private val repository: KeyguardTransitionRepository, private val fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor, private val fromPrimaryBouncerTransitionInteractor: FromPrimaryBouncerTransitionInteractor, @@ -43,45 +51,63 @@ constructor( ) { /** - * Called to start a transition that will ultimately dismiss the keyguard from the current - * state. + * Launches a coroutine to start a transition that will ultimately dismiss the keyguard from the + * current state. * * This is called exclusively by sources that can authoritatively say we should be unlocked, * including KeyguardSecurityContainerController and WindowManager. * - * Returns [false] if the transition was not started, because we're already GONE or we don't - * know how to dismiss keyguard from the current state. + * This is one of the few transitions that is started outside of the From*TransitionInteractor + * classes. This is because this is an external call that must be respected, so it doesn't + * matter what state we're in/coming from - we must transition from that state to GONE. + * + * Invokes [onAlreadyGone] if the transition was not started because we're already GONE by the + * time the coroutine runs. */ - fun startDismissKeyguardTransition(reason: String = ""): Boolean { - if (SceneContainerFlag.isEnabled) return false + @JvmOverloads + fun startDismissKeyguardTransition(reason: String = "", onAlreadyGone: (() -> Unit)? = null) { + if (SceneContainerFlag.isEnabled) return Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)") - val startedState = - if (transitionRaceCondition()) { - repository.currentTransitionInfo.to + + scope.launch { + val startedState = + if (transitionRaceCondition()) { + repository.currentTransitionInfo.to + } else { + repository.currentTransitionInfoInternal.value.to + } + + val animator: ValueAnimator? = + when (startedState) { + LOCKSCREEN -> fromLockscreenTransitionInteractor + PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor + ALTERNATE_BOUNCER -> fromAlternateBouncerTransitionInteractor + AOD -> fromAodTransitionInteractor + DOZING -> fromDozingTransitionInteractor + OCCLUDED -> fromOccludedTransitionInteractor + else -> null + }?.getDefaultAnimatorForTransitionsToState(KeyguardState.GONE) + + if (startedState != KeyguardState.GONE && animator != null) { + repository.startTransition( + TransitionInfo( + "KeyguardDismissTransitionInteractor" + + if (reason.isNotBlank()) "($reason)" else "", + startedState, + KeyguardState.GONE, + animator, + TransitionModeOnCanceled.LAST_VALUE, + ) + ) } else { - repository.currentTransitionInfoInternal.value.to - } - when (startedState) { - LOCKSCREEN -> fromLockscreenTransitionInteractor.dismissKeyguard() - PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor.dismissPrimaryBouncer() - ALTERNATE_BOUNCER -> fromAlternateBouncerTransitionInteractor.dismissAlternateBouncer() - AOD -> fromAodTransitionInteractor.dismissAod() - DOZING -> fromDozingTransitionInteractor.dismissFromDozing() - KeyguardState.OCCLUDED -> fromOccludedTransitionInteractor.dismissFromOccluded() - KeyguardState.GONE -> { Log.i( TAG, - "Already transitioning to GONE; ignoring startDismissKeyguardTransition.", + "Can't transition to GONE from $startedState; " + + "ignoring startDismissKeyguardTransition.", ) - return false - } - else -> { - Log.e(TAG, "We don't know how to dismiss keyguard from state $startedState.") - return false + onAlreadyGone?.invoke() } } - - return true } companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt index 213083db71c9..9c886b228ca9 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt @@ -31,6 +31,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.shared.R as sharedR import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.flow.combine object KeyguardSmartspaceViewBinder { @JvmStatic @@ -43,21 +44,25 @@ object KeyguardSmartspaceViewBinder { return keyguardRootView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { launch("$TAG#clockViewModel.hasCustomWeatherDataDisplay") { - clockViewModel.hasCustomWeatherDataDisplay.collect { hasCustomWeatherDataDisplay - -> - updateDateWeatherToBurnInLayer( - keyguardRootView, - clockViewModel, - smartspaceViewModel, + combine( + smartspaceViewModel.isWeatherVisible, + clockViewModel.hasCustomWeatherDataDisplay, + ::Pair, ) - blueprintInteractor.refreshBlueprint( - Config( - Type.SmartspaceVisibility, - checkPriority = false, - terminatePrevious = false, + .collect { + updateDateWeatherToBurnInLayer( + keyguardRootView, + clockViewModel, + smartspaceViewModel, ) - ) - } + blueprintInteractor.refreshBlueprint( + Config( + Type.SmartspaceVisibility, + checkPriority = false, + terminatePrevious = false, + ) + ) + } } launch("$TAG#smartspaceViewModel.bcSmartspaceVisibility") { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt index cd038d799f42..9319bc890c6c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt @@ -23,6 +23,8 @@ import android.view.ViewTreeObserver.OnGlobalLayoutListener import androidx.constraintlayout.widget.Barrier import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import androidx.constraintlayout.widget.ConstraintSet.GONE +import androidx.constraintlayout.widget.ConstraintSet.VISIBLE import com.android.systemui.customization.R as customR import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.KeyguardUnlockAnimationController @@ -195,24 +197,13 @@ constructor( smartspaceController.requestSmartspaceUpdate() constraintSet.apply { - val weatherVisibility = - when (keyguardSmartspaceViewModel.isWeatherVisible.value) { - true -> ConstraintSet.VISIBLE - false -> ConstraintSet.GONE - } - setVisibility(sharedR.id.weather_smartspace_view, weatherVisibility) - setAlpha( - sharedR.id.weather_smartspace_view, - if (weatherVisibility == View.VISIBLE) 1f else 0f, - ) - val dateVisibility = - if (keyguardClockViewModel.hasCustomWeatherDataDisplay.value) ConstraintSet.GONE - else ConstraintSet.VISIBLE - setVisibility(sharedR.id.date_smartspace_view, dateVisibility) - setAlpha( - sharedR.id.date_smartspace_view, - if (dateVisibility == ConstraintSet.VISIBLE) 1f else 0f, - ) + val showWeather = keyguardSmartspaceViewModel.isWeatherVisible.value + setVisibility(sharedR.id.weather_smartspace_view, if (showWeather) VISIBLE else GONE) + setAlpha(sharedR.id.weather_smartspace_view, if (showWeather) 1f else 0f) + + val showDateView = !keyguardClockViewModel.hasCustomWeatherDataDisplay.value + setVisibility(sharedR.id.date_smartspace_view, if (showDateView) VISIBLE else GONE) + setAlpha(sharedR.id.date_smartspace_view, if (showDateView) 1f else 0f) } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt index 92bb5e6029cb..733d7d71061e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt @@ -30,7 +30,6 @@ import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.scene.ui.composable.transitions.TO_BOUNCER_FADE_FRACTION -import com.android.systemui.window.flag.WindowBlurFlag import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow @@ -73,7 +72,7 @@ constructor( onStep = alphaForAnimationStep, ) - val lockscreenAlpha: Flow<Float> = if (WindowBlurFlag.isEnabled) alphaFlow else emptyFlow() + val lockscreenAlpha: Flow<Float> = if (Flags.bouncerUiRevamp()) alphaFlow else emptyFlow() val notificationAlpha: Flow<Float> = if (Flags.bouncerUiRevamp()) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt index f5e0c81ca9a2..b1a2ec92401a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt @@ -20,7 +20,6 @@ import android.animation.FloatEvaluator import android.animation.IntEvaluator import com.android.keyguard.KeyguardViewController import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor -import com.android.systemui.biometrics.shared.model.SensorLocation import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor @@ -34,6 +33,7 @@ import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition import com.android.systemui.keyguard.ui.view.DeviceEntryIconView import com.android.systemui.scene.shared.flag.SceneContainerFlag import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shared.customization.data.SensorLocation import com.android.systemui.util.kotlin.sample import dagger.Lazy import javax.inject.Inject diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt index 8fe225a8b93f..88fdc83fa7a0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt @@ -100,7 +100,7 @@ constructor( keyguardClockInteractor.clockShouldBeCentered.stateIn( scope = applicationScope, started = SharingStarted.WhileSubscribed(), - initialValue = false, + initialValue = true, ) // To translate elements below smartspace in weather clock to avoid overlapping between date diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt index 5ee80a7b7442..f8425c16c341 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt @@ -77,7 +77,7 @@ constructor( isWeatherVisible( clockIncludesCustomWeatherDisplay = keyguardClockViewModel.hasCustomWeatherDataDisplay.value, - isWeatherEnabled = smartspaceInteractor.isWeatherEnabled.value, + isWeatherEnabled = isWeatherEnabled.value, ), ) diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt index a6b9442b1270..71c8d1f5b4c7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/Media3ActionFactory.kt @@ -130,7 +130,7 @@ constructor( null, // no action to perform when clicked context.getString(R.string.controls_media_button_connecting), if (Flags.mediaControlsUiUpdate()) { - context.getDrawable(R.drawable.ic_media_connecting_status_container) + context.getDrawable(R.drawable.ic_media_connecting_button_container) } else { context.getDrawable(R.drawable.ic_media_connecting_container) }, diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt index 9bf556cf07c2..5fef81f4596a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaActions.kt @@ -71,7 +71,7 @@ fun createActionsFromState( null, // no action to perform when clicked context.getString(R.string.controls_media_button_connecting), if (Flags.mediaControlsUiUpdate()) { - context.getDrawable(R.drawable.ic_media_connecting_status_container) + context.getDrawable(R.drawable.ic_media_connecting_button_container) } else { context.getDrawable(R.drawable.ic_media_connecting_container) }, 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 4e97eb5bc9d1..47161191b229 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 @@ -1744,7 +1744,8 @@ constructor( println("location: $desiredLocation") println( "state: ${desiredHostState?.expansion}, " + - "only active ${desiredHostState?.showsOnlyActiveMedia}" + "only active ${desiredHostState?.showsOnlyActiveMedia}, " + + "visible ${desiredHostState?.visible}" ) println("isSwipedAway: ${MediaPlayerData.isSwipedAway}") println("allowMediaPlayerOnLockScreen: $allowMediaPlayerOnLockScreen") diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt index b4dabbe036e9..a6aa159692ec 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManager.kt @@ -37,12 +37,14 @@ import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.launchTraced as launch import com.android.app.tracing.traceSection import com.android.keyguard.KeyguardViewController +import com.android.systemui.Dumpable import com.android.systemui.Flags.mediaControlsLockscreenShadeBugFix import com.android.systemui.communal.ui.viewmodel.CommunalTransitionViewModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dreams.DreamOverlayStateController +import com.android.systemui.dump.DumpManager import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.media.controls.domain.pipeline.MediaDataManager @@ -62,6 +64,7 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SplitShadeStateController import com.android.systemui.util.animation.UniqueObjectHostView import com.android.systemui.util.settings.SecureSettings +import java.io.PrintWriter import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -119,7 +122,8 @@ constructor( @Application private val coroutineScope: CoroutineScope, private val splitShadeStateController: SplitShadeStateController, private val logger: MediaViewLogger, -) { + private val dumpManager: DumpManager, +) : Dumpable { /** Track the media player setting status on lock screen. */ private var allowMediaPlayerOnLockScreen: Boolean = true @@ -476,6 +480,7 @@ constructor( } init { + dumpManager.registerNormalDumpable(TAG, this) updateConfiguration() configurationController.addCallback( object : ConfigurationController.ConfigurationListener { @@ -1344,6 +1349,19 @@ constructor( return isCommunalShowing && !isPrimaryBouncerShowing && !isAnyShadeFullyExpanded } + override fun dump(pw: PrintWriter, args: Array<out String>) { + pw.apply { + println( + "current attachment: $currentAttachmentLocation, " + + "desired location: $desiredLocation, " + + "visible ${getHost(desiredLocation)?.visible}" + ) + println("previous location: $previousLocation") + println("bounds: $currentBounds, target $targetBounds") + println("clipping: $currentClipping, target $targetClipping") + } + } + companion object { /** Attached in expanded quick settings */ const val LOCATION_QS = 0 diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt index a2ddc20844e7..86e92941256b 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt @@ -883,7 +883,6 @@ constructor( currentEndLocation = endLocation currentStartLocation = startLocation currentTransitionProgress = transitionProgress - logger.logMediaLocation("setCurrentState", startLocation, endLocation) val shouldAnimate = animateNextStateChange && !applyImmediately @@ -900,6 +899,7 @@ constructor( // If the view isn't bound, we can drop the animation, otherwise we'll execute it animateNextStateChange = false if (transitionLayout == null) { + logger.logMediaLocation("setCurrentState: view not bound", startLocation, endLocation) return } @@ -949,7 +949,7 @@ constructor( ) } logger.logMediaSize( - "setCurrentState (progress $transitionProgress)", + "setCurrentState $startLocation -> $endLocation (progress $transitionProgress)", result.width, result.height, ) diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java index 40f59744e038..7f1c7a525f97 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java @@ -18,6 +18,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.shared.plugins.PluginEnabler; @@ -28,6 +29,7 @@ import javax.inject.Singleton; /** */ @Singleton public class PluginEnablerImpl implements PluginEnabler { + private static final String TAG = "PluginEnablerImpl"; private static final String CRASH_DISABLED_PLUGINS_PREF_FILE = "auto_disabled_plugins_prefs"; private final PackageManager mPm; @@ -64,8 +66,13 @@ public class PluginEnablerImpl implements PluginEnabler { @Override public boolean isEnabled(ComponentName component) { - return mPm.getComponentEnabledSetting(component) - != PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + try { + return mPm.getComponentEnabledSetting(component) + != PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + } catch (IllegalArgumentException ex) { + Log.e(TAG, "Package Manager Exception", ex); + return false; + } } @Override @@ -73,6 +80,6 @@ public class PluginEnablerImpl implements PluginEnabler { if (isEnabled(componentName)) { return ENABLED; } - return mAutoDisabledPrefs.getInt(componentName.flattenToString(), DISABLED_MANUALLY); + return mAutoDisabledPrefs.getInt(componentName.flattenToString(), DISABLED_UNKNOWN); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt index 56fece8ecf5c..b53685ee3cd4 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt @@ -88,11 +88,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.compose.animation.scene.ContentKey +import com.android.compose.animation.scene.ContentScope import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.ElementMatcher import com.android.compose.animation.scene.MutableSceneTransitionLayoutState import com.android.compose.animation.scene.SceneKey -import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.SceneTransitionLayout import com.android.compose.animation.scene.content.state.TransitionState import com.android.compose.animation.scene.transitions @@ -100,6 +100,7 @@ import com.android.compose.modifiers.height import com.android.compose.modifiers.padding import com.android.compose.modifiers.thenIf import com.android.compose.theme.PlatformTheme +import com.android.mechanics.GestureContext import com.android.systemui.Dumpable import com.android.systemui.brightness.ui.compose.BrightnessSliderContainer import com.android.systemui.compose.modifiers.sysuiResTag @@ -579,7 +580,7 @@ constructor( } @Composable - private fun SceneScope.QuickQuickSettingsElement() { + private fun ContentScope.QuickQuickSettingsElement() { val qqsPadding = viewModel.qqsHeaderHeight val bottomPadding = viewModel.qqsBottomPadding DisposableEffect(Unit) { @@ -663,7 +664,7 @@ constructor( } @Composable - private fun SceneScope.QuickSettingsElement() { + private fun ContentScope.QuickSettingsElement() { val qqsPadding = viewModel.qqsHeaderHeight val qsExtraPadding = dimensionResource(R.dimen.qs_panel_padding_top) Column( @@ -935,6 +936,8 @@ private class ExpansionTransition(currentProgress: Float) : override val isUserInputOngoing: Boolean get() = true + override val gestureContext: GestureContext? = null + private val finishCompletable = CompletableDeferred<Unit>() override suspend fun run() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt index 3fd87689b169..e2a39160defc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt @@ -54,11 +54,11 @@ interface QSModuleBase { /** A map of internal QS tiles. Ensures that this can be injected even if it is empty */ @Multibinds fun tileMap(): Map<String?, QSTileImpl<*>?>? - @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl?): QSSceneAdapter? + @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl): QSSceneAdapter /** Dims the screen */ @Binds fun bindReduceBrightColorsController( - impl: ReduceBrightColorsControllerImpl? - ): ReduceBrightColorsController? + impl: ReduceBrightColorsControllerImpl + ): ReduceBrightColorsController } diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt index a22eb3a8d517..185ea93387a3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt @@ -18,7 +18,7 @@ package com.android.systemui.qs.panels.ui.compose import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.qs.panels.shared.model.SizedTile import com.android.systemui.qs.panels.shared.model.TileRow import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel @@ -27,7 +27,7 @@ import com.android.systemui.qs.pipeline.shared.TileSpec /** A layout of tiles, indicating how they should be composed when showing in QS or in edit mode. */ interface GridLayout { - @Composable fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) + @Composable fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) @Composable fun EditTileGrid( diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt index 39408d3dee72..c72381f45239 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt @@ -40,7 +40,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInteropFilter import androidx.compose.ui.unit.dp -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.compose.modifiers.padding import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.development.ui.compose.BuildNumber @@ -63,7 +63,7 @@ constructor( @PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout, ) : GridLayout by delegateGridLayout { @Composable - override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) { + override fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) { val viewModel = rememberViewModel(traceName = "PaginatedGridLayout-TileGrid") { viewModelFactory.create() diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt index 8fda23d54625..5cb30b999e13 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.util.fastMap import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.compose.modifiers.sysuiResTag import com.android.systemui.grid.ui.compose.VerticalSpannedGrid import com.android.systemui.qs.composefragment.ui.GridAnchor @@ -38,7 +38,7 @@ import com.android.systemui.qs.shared.ui.ElementKeys.toElementKey import com.android.systemui.res.R @Composable -fun SceneScope.QuickQuickSettings( +fun ContentScope.QuickQuickSettings( viewModel: QuickQuickSettingsViewModel, modifier: Modifier = Modifier, ) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt index 6c1906bb906f..bcc44d397eb2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt @@ -20,11 +20,11 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel @Composable -fun SceneScope.TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) { +fun ContentScope.TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) { val gridLayout by viewModel.gridLayout.collectAsStateWithLifecycle() val tiles by viewModel.tileViewModels.collectAsStateWithLifecycle(emptyList()) diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt index 66961b6efe46..4432d336237f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt @@ -26,7 +26,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.util.fastMap import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ContentScope import com.android.systemui.dagger.SysUISingleton import com.android.systemui.grid.ui.compose.VerticalSpannedGrid import com.android.systemui.haptics.msdl.qs.TileHapticsViewModelFactoryProvider @@ -58,7 +58,7 @@ constructor( ) : PaginatableGridLayout { @Composable - override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) { + override fun ContentScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) { DisposableEffect(tiles) { val token = Any() tiles.forEach { it.startListening(token) } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 04f0b8736598..1e8ef359bb71 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -42,7 +42,7 @@ import androidx.annotation.Nullable; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settingslib.notification.modes.EnableZenModeDialog; +import com.android.settingslib.notification.modes.EnableDndDialogFactory; import com.android.systemui.Prefs; import com.android.systemui.animation.DialogCuj; import com.android.systemui.animation.DialogTransitionAnimator; @@ -59,7 +59,7 @@ import com.android.systemui.qs.QsEventLogger; import com.android.systemui.qs.UserSettingObserver; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; -import com.android.systemui.qs.tiles.dialog.QSZenModeDialogMetricsLogger; +import com.android.systemui.qs.tiles.dialog.QSEnableDndDialogMetricsLogger; import com.android.systemui.res.R; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.ZenModeController; @@ -84,7 +84,7 @@ public class DndTile extends QSTileImpl<BooleanState> { private final SharedPreferences mSharedPreferences; private final UserSettingObserver mSettingZenDuration; private final DialogTransitionAnimator mDialogTransitionAnimator; - private final QSZenModeDialogMetricsLogger mQSZenDialogMetricsLogger; + private final QSEnableDndDialogMetricsLogger mQSDndDurationDialogLogger; private boolean mListening; @@ -121,7 +121,7 @@ public class DndTile extends QSTileImpl<BooleanState> { refreshState(); } }; - mQSZenDialogMetricsLogger = new QSZenModeDialogMetricsLogger(mContext); + mQSDndDurationDialogLogger = new QSEnableDndDialogMetricsLogger(mContext); } public static void setVisible(Context context, boolean visible) { @@ -201,9 +201,9 @@ public class DndTile extends QSTileImpl<BooleanState> { } private Dialog makeZenModeDialog() { - AlertDialog dialog = new EnableZenModeDialog(mContext, R.style.Theme_SystemUI_Dialog, + AlertDialog dialog = new EnableDndDialogFactory(mContext, R.style.Theme_SystemUI_Dialog, true /* cancelIsNeutral */, - mQSZenDialogMetricsLogger).createDialog(); + mQSDndDurationDialogLogger).createDialog(); SystemUIDialog.applyFlags(dialog); SystemUIDialog.setShowForAllUsers(dialog, true); SystemUIDialog.registerDismissListener(dialog); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java index e93cec875429..42b35c736d42 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java @@ -191,8 +191,9 @@ public class ScreenRecordTile extends QSTileImpl<QSTile.BooleanState> @Override public boolean getDetailsViewModel(Consumer<TileDetailsViewModel> callback) { - handleClick(() -> - callback.accept(new ScreenRecordDetailsViewModel()) + handleClick(() -> executeWhenUnlockedKeyguard( + () -> callback.accept(new ScreenRecordDetailsViewModel(mController, + this::onStartRecordingClicked))) ); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java index 340cb68a83a4..6b5a22a4fc09 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java @@ -1506,15 +1506,17 @@ public class InternetDetailsContentController implements AccessPointController.A Intent getConfiguratorQrCodeGeneratorIntentOrNull(WifiEntry wifiEntry) { if (!mFeatureFlags.isEnabled(Flags.SHARE_WIFI_QS_BUTTON) || wifiEntry == null - || mWifiManager == null || !wifiEntry.canShare() - || wifiEntry.getWifiConfiguration() == null) { + || mWifiManager == null || !wifiEntry.canShare()) { + return null; + } + var wifiConfiguration = wifiEntry.getWifiConfiguration(); + if (wifiConfiguration == null) { return null; } Intent intent = new Intent(); intent.setAction(WifiDppIntentHelper.ACTION_CONFIGURATOR_AUTH_QR_CODE_GENERATOR); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - WifiDppIntentHelper.setConfiguratorIntentExtra(intent, mWifiManager, - wifiEntry.getWifiConfiguration()); + WifiDppIntentHelper.setConfiguratorIntentExtra(intent, mWifiManager, wifiConfiguration); return intent; } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSEnableDndDialogMetricsLogger.java index b3f66a6bf9dd..5196a22df29a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSEnableDndDialogMetricsLogger.java @@ -19,7 +19,7 @@ package com.android.systemui.qs.tiles.dialog; import android.content.Context; import com.android.internal.logging.UiEventLogger; -import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger; +import com.android.settingslib.notification.modes.EnableDndDialogMetricsLogger; import com.android.systemui.qs.QSDndEvent; import com.android.systemui.qs.QSEvents; @@ -30,10 +30,10 @@ import com.android.systemui.qs.QSEvents; * * Other names for DND (Do Not Disturb) include "Zen" and "Priority only". */ -public class QSZenModeDialogMetricsLogger extends ZenModeDialogMetricsLogger { +public class QSEnableDndDialogMetricsLogger extends EnableDndDialogMetricsLogger { private final UiEventLogger mUiEventLogger = QSEvents.INSTANCE.getQsUiEventsLogger(); - public QSZenModeDialogMetricsLogger(Context context) { + public QSEnableDndDialogMetricsLogger(Context context) { super(context); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt index 42cb1248ccff..54e4a521c239 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt @@ -17,27 +17,45 @@ package com.android.systemui.qs.tiles.dialog import android.view.LayoutInflater +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import com.android.systemui.plugins.qs.TileDetailsViewModel import com.android.systemui.res.R +import com.android.systemui.screenrecord.RecordingController +import com.android.systemui.screenrecord.ScreenRecordPermissionViewBinder /** The view model used for the screen record details view in the Quick Settings */ -class ScreenRecordDetailsViewModel() : TileDetailsViewModel() { +class ScreenRecordDetailsViewModel( + private val recordingController: RecordingController, + private val onStartRecordingClicked: Runnable, +) : TileDetailsViewModel() { + + private var viewBinder: ScreenRecordPermissionViewBinder = + recordingController.createScreenRecordPermissionViewBinder(onStartRecordingClicked) + @Composable override fun GetContentView() { // TODO(b/378514312): Finish implementing this function. + + if (recordingController.isScreenCaptureDisabled) { + // TODO(b/388345506): Show disabled page here. + return + } + AndroidView( - modifier = Modifier.fillMaxWidth().heightIn(max = VIEW_MAX_HEIGHT), + modifier = Modifier.fillMaxWidth().fillMaxHeight(), factory = { context -> // Inflate with the existing dialog xml layout - LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null) + val view = LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null) + viewBinder.bind(view) + + view + // TODO(b/378514473): Revamp the details view according to the spec. }, + onRelease = { viewBinder.unbind() }, ) } @@ -54,8 +72,4 @@ class ScreenRecordDetailsViewModel() : TileDetailsViewModel() { // No sub-title in this tile. return "" } - - companion object { - private val VIEW_MAX_HEIGHT: Dp = 320.dp - } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt index 594394f68d48..5ce7f0d039c8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt @@ -29,6 +29,7 @@ import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate +import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger import javax.inject.Inject @SysUISingleton @@ -39,6 +40,7 @@ constructor( // TODO(b/353896370): The domain layer should not have to depend on the UI layer. private val dialogDelegate: ModesDialogDelegate, private val zenModeInteractor: ZenModeInteractor, + private val dialogEventLogger: ModesDialogEventLogger, ) : QSTileUserActionInteractor<ModesTileModel> { val longClickIntent = Intent(Settings.ACTION_ZEN_MODE_SETTINGS) @@ -78,7 +80,16 @@ constructor( Log.wtf(TAG, "Triggered DND but it's null!?") return } - zenModeInteractor.activateMode(dnd) + + if (zenModeInteractor.shouldAskForZenDuration(dnd)) { + dialogEventLogger.logOpenDurationDialog(dnd) + // NOTE: The dialog handles turning on the mode itself. + val dialog = dialogDelegate.makeDndDurationDialog() + dialog.show() + } else { + dialogEventLogger.logModeOn(dnd) + zenModeInteractor.activateMode(dnd) + } } else { zenModeInteractor.deactivateAllModes() } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index e3cf41191384..adf9eb44e162 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -58,6 +58,7 @@ import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.Looper; import android.os.PatternMatcher; import android.os.Process; @@ -146,7 +147,6 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis public static final String TAG_OPS = "OverviewProxyService"; private static final long BACKOFF_MILLIS = 1000; private static final long DEFERRED_CALLBACK_MILLIS = 5000; - // Max backoff caps at 5 mins private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000; @@ -183,6 +183,10 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private int mConnectionBackoffAttempts; private boolean mBound; private boolean mIsEnabled; + // This is set to false when the overview service is requested to be bound until it is notified + // that the previous service has been cleaned up in IOverviewProxy#onUnbind(). It is also set to + // true after a 1000ms timeout by mDeferredBindAfterTimedOutCleanup. + private boolean mIsPrevServiceCleanedUp = true; private boolean mIsSystemOrVisibleBgUser; private int mCurrentBoundedUserId = -1; @@ -489,6 +493,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis retryConnectionWithBackoff(); }; + private final Runnable mDeferredBindAfterTimedOutCleanup = () -> { + Log.w(TAG_OPS, "Timed out waiting for previous service to clean up, binding to new one"); + mIsPrevServiceCleanedUp = true; + maybeBindService(); + }; + private final BroadcastReceiver mUserEventReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -859,6 +869,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mShadeViewControllerLazy.get().cancelInputFocusTransfer(); }); } + mIsPrevServiceCleanedUp = true; startConnectionToCurrentUser(); } @@ -889,6 +900,19 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis } mHandler.removeCallbacks(mConnectionRunnable); + maybeBindService(); + } + + private void maybeBindService() { + if (!mIsPrevServiceCleanedUp) { + Log.w(TAG_OPS, "Skipping connection to TouchInteractionService until previous" + + " instance is cleaned up."); + if (!mHandler.hasCallbacks(mDeferredConnectionCallback)) { + mHandler.postDelayed(mDeferredBindAfterTimedOutCleanup, BACKOFF_MILLIS); + } + return; + } + // Avoid creating TouchInteractionService because the System user in HSUM mode does not // interact with UI elements UserHandle currentUser = UserHandle.of(mUserTracker.getUserId()); @@ -907,6 +931,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis Log.e(TAG_OPS, "Unable to bind because of security error", e); } if (mBound) { + mIsPrevServiceCleanedUp = false; // Ensure that connection has been established even if it thinks it is bound mHandler.postDelayed(mDeferredConnectionCallback, DEFERRED_CALLBACK_MILLIS); } else { @@ -960,6 +985,24 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis // Always unbind the service (ie. if called through onNullBinding or onBindingDied) mContext.unbindService(mOverviewServiceConnection); mBound = false; + if (mOverviewProxy != null) { + try { + mOverviewProxy.onUnbind(new IRemoteCallback.Stub() { + @Override + public void sendResult(Bundle data) throws RemoteException { + // Received Launcher reply, try to bind anew. + mIsPrevServiceCleanedUp = true; + if (mHandler.hasCallbacks(mDeferredBindAfterTimedOutCleanup)) { + mHandler.removeCallbacks(mDeferredBindAfterTimedOutCleanup); + maybeBindService(); + } + } + }); + } catch (RemoteException e) { + Log.w(TAG_OPS, "disconnectFromLauncherService failed to notify Launcher"); + mIsPrevServiceCleanedUp = true; + } + } } if (mOverviewProxy != null) { @@ -1189,6 +1232,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis pw.print(" mInputFocusTransferStartMillis="); pw.println(mInputFocusTransferStartMillis); pw.print(" mActiveNavBarRegion="); pw.println(mActiveNavBarRegion); pw.print(" mNavBarMode="); pw.println(mNavBarMode); + pw.print(" mIsPrevServiceCleanedUp="); pw.println(mIsPrevServiceCleanedUp); mSysUiState.dump(pw, args); } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt index 3a23a71cf7bf..8657c1723507 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt @@ -94,7 +94,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChangedBy -import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.filterNot @@ -717,14 +716,7 @@ constructor( } applicationScope.launch { - keyguardInteractor.isAodAvailable - .flatMapLatest { isAodAvailable -> - if (!isAodAvailable) { - powerInteractor.detailedWakefulness - } else { - emptyFlow() - } - } + powerInteractor.detailedWakefulness .distinctUntilChangedBy { it.isAwake() } .collect { wakefulness -> when { diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java index 9ee99e45ceeb..140fbf340f8b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java @@ -70,6 +70,8 @@ public class RecordingController private final ScreenCaptureDisabledDialogDelegate mScreenCaptureDisabledDialogDelegate; private final ScreenRecordPermissionDialogDelegate.Factory mScreenRecordPermissionDialogDelegateFactory; + private final ScreenRecordPermissionViewBinder.Factory + mScreenRecordPermissionViewBinderFactory; protected static final String INTENT_UPDATE_STATE = "com.android.systemui.screenrecord.UPDATE_STATE"; @@ -118,7 +120,8 @@ public class RecordingController MediaProjectionMetricsLogger mediaProjectionMetricsLogger, ScreenCaptureDisabledDialogDelegate screenCaptureDisabledDialogDelegate, ScreenRecordPermissionDialogDelegate.Factory - screenRecordPermissionDialogDelegateFactory) { + screenRecordPermissionDialogDelegateFactory, + ScreenRecordPermissionViewBinder.Factory screenRecordPermissionViewBinderFactory) { mMainExecutor = mainExecutor; mDevicePolicyResolver = devicePolicyResolver; mBroadcastDispatcher = broadcastDispatcher; @@ -127,6 +130,7 @@ public class RecordingController mMediaProjectionMetricsLogger = mediaProjectionMetricsLogger; mScreenCaptureDisabledDialogDelegate = screenCaptureDisabledDialogDelegate; mScreenRecordPermissionDialogDelegateFactory = screenRecordPermissionDialogDelegateFactory; + mScreenRecordPermissionViewBinderFactory = screenRecordPermissionViewBinderFactory; BroadcastOptions options = BroadcastOptions.makeBasic(); options.setInteractive(true); @@ -151,8 +155,7 @@ public class RecordingController * If screen capturing is currently not allowed it will return a dialog * that warns users about it. */ public Dialog createScreenRecordDialog(@Nullable Runnable onStartRecordingClicked) { - if (mDevicePolicyResolver.get() - .isScreenCaptureCompletelyDisabled(getHostUserHandle())) { + if (isScreenCaptureDisabled()) { return mScreenCaptureDisabledDialogDelegate.createSysUIDialog(); } @@ -165,6 +168,27 @@ public class RecordingController } /** + * Create a view binder that controls the logic of views inside the screen record permission + * view. + * @param onStartRecordingClicked the callback that is run when the start button is clicked. + */ + public ScreenRecordPermissionViewBinder createScreenRecordPermissionViewBinder( + @Nullable Runnable onStartRecordingClicked + ) { + return mScreenRecordPermissionViewBinderFactory + .create(getHostUserHandle(), getHostUid(), this, + onStartRecordingClicked); + } + + /** + * Check if screen capture is currently disabled for this device and user. + */ + public boolean isScreenCaptureDisabled() { + return mDevicePolicyResolver.get() + .isScreenCaptureCompletelyDisabled(getHostUserHandle()); + } + + /** * Start counting down in preparation to start a recording * @param ms Total time in ms to wait before starting * @param interval Time in ms per countdown step diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt index 9fcb3dfc0ad3..23df1c5441bf 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionViewBinder.kt @@ -49,6 +49,9 @@ import com.android.systemui.mediaprojection.permission.ScreenShareOption import com.android.systemui.plugins.ActivityStarter import com.android.systemui.res.R import com.android.systemui.settings.UserContextProvider +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject class ScreenRecordPermissionViewBinder( private val hostUserHandle: UserHandle, @@ -68,6 +71,38 @@ class ScreenRecordPermissionViewBinder( mediaProjectionMetricsLogger, defaultSelectedMode, ) { + @AssistedInject + constructor( + @Assisted hostUserHandle: UserHandle, + @Assisted hostUid: Int, + mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, + displayManager: DisplayManager, + @Assisted controller: RecordingController, + activityStarter: ActivityStarter, + userContextProvider: UserContextProvider, + @Assisted onStartRecordingClicked: Runnable?, + ) : this( + hostUserHandle, + hostUid, + mediaProjectionMetricsLogger, + defaultSelectedMode = SINGLE_APP, + displayManager, + controller, + activityStarter, + userContextProvider, + onStartRecordingClicked, + ) + + @AssistedFactory + interface Factory { + fun create( + hostUserHandle: UserHandle, + hostUid: Int, + recordingController: RecordingController, + onStartRecordingClicked: Runnable?, + ): ScreenRecordPermissionViewBinder + } + private lateinit var tapsSwitch: Switch private lateinit var audioSwitch: Switch private lateinit var tapsView: View diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java index 0650f8606ba9..9a1ffcbab8d1 100644 --- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimDrawable.java @@ -35,7 +35,6 @@ import android.view.animation.DecelerateInterpolator; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.graphics.ColorUtils; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; -import com.android.systemui.window.flag.WindowBlurFlag; /** * Drawable used on SysUI scrims. @@ -214,10 +213,6 @@ public class ScrimDrawable extends Drawable { public void draw(@NonNull Canvas canvas) { mPaint.setColor(mMainColor); mPaint.setAlpha(mAlpha); - if (WindowBlurFlag.isEnabled()) { - // TODO (b/381263600), wire this at ScrimController, move it to PrimaryBouncerTransition - mPaint.setAlpha((int) (0.5f * mAlpha)); - } if (mConcaveInfo != null) { drawConcave(canvas); } else if (mCornerRadiusEnabled && mCornerRadius > 0) { diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java index 03a8d17847f9..49f3cfc4ceaf 100644 --- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java @@ -39,10 +39,8 @@ import androidx.core.graphics.ColorUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.colorextraction.ColorExtractor; -import com.android.systemui.res.R; import com.android.systemui.shade.TouchLogger; import com.android.systemui.util.LargeScreenUtils; -import com.android.systemui.window.flag.WindowBlurFlag; import java.util.concurrent.Executor; @@ -252,13 +250,6 @@ public class ScrimView extends View { if (mBlendWithMainColor) { mainTinted = ColorUtils.blendARGB(mColors.getMainColor(), mTintColor, tintAmount); } - if (WindowBlurFlag.isEnabled()) { - int layerAbove = ColorUtils.setAlphaComponent( - getResources().getColor(R.color.shade_panel, null), - (int) (0.4f * 255)); - int layerBelow = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.1f * 255)); - mainTinted = ColorUtils.compositeColors(layerAbove, layerBelow); - } drawable.setColor(mainTinted, animated); } else { boolean hasAlpha = Color.alpha(mTintColor) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/shade/OWNERS b/packages/SystemUI/src/com/android/systemui/shade/OWNERS index 5b8277284117..89454b84a528 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/shade/OWNERS @@ -1,5 +1,7 @@ justinweir@google.com syeonlee@google.com +nicomazz@google.com +burakov@google.com per-file *Notification* = set noparent per-file *Notification* = file:../statusbar/notification/OWNERS @@ -9,13 +11,13 @@ per-file NotificationsQSContainerController.kt = kozynski@google.com, asc@google per-file *ShadeHeader* = syeonlee@google.com, kozynski@google.com, asc@google.com per-file *Interactor* = set noparent -per-file *Interactor* = justinweir@google.com, syeonlee@google.com, nijamkin@google.com +per-file *Interactor* = justinweir@google.com, syeonlee@google.com, nijamkin@google.com, nicomazz@google.com, burakov@google.com per-file *Repository* = set noparent -per-file *Repository* = justinweir@google.com, syeonlee@google.com, nijamkin@google.com +per-file *Repository* = justinweir@google.com, syeonlee@google.com, nijamkin@google.com, nicomazz@google.com, burakov@google.com -per-file NotificationShadeWindow* = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com +per-file NotificationShadeWindow* = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com, nicomazz@google.com, burakov@google.com per-file NotificationPanelUnfoldAnimationController.kt = alexflo@google.com, jeffdq@google.com, juliacr@google.com -per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com -per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com +per-file NotificationPanelView.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com, nicomazz@google.com, burakov@google.com +per-file NotificationPanelViewController.java = pixel@google.com, cinek@google.com, juliacr@google.com, justinweir@google.com, syeonlee@google.com, nicomazz@google.com, burakov@google.com diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt index f67d33122063..fc26499a27a7 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt @@ -91,8 +91,10 @@ constructor( try { withContext(mainThreadContext) { traceReparenting { - shadeDisplayChangeLatencyTracker.onShadeDisplayChanging(destinationId) - collapseAndExpandShadeIfNeeded { reparentToDisplayId(id = destinationId) } + collapseAndExpandShadeIfNeeded { + shadeDisplayChangeLatencyTracker.onShadeDisplayChanging(destinationId) + reparentToDisplayId(id = destinationId) + } checkContextDisplayMatchesExpected(destinationId) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java index af51c49204bb..fed3f6e81130 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ImmersiveModeConfirmation.java @@ -22,8 +22,6 @@ import static android.app.StatusBarManager.DISABLE_BACK; import static android.app.StatusBarManager.DISABLE_HOME; import static android.app.StatusBarManager.DISABLE_RECENT; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.ViewRootImpl.CLIENT_IMMERSIVE_CONFIRMATION; -import static android.view.ViewRootImpl.CLIENT_TRANSIENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; import static android.window.DisplayAreaOrganizer.KEY_ROOT_DISPLAY_AREA_ID; @@ -90,8 +88,8 @@ import kotlin.Lazy; import javax.inject.Inject; /** - * Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden - * entering immersive mode. + * Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden + * entering immersive mode. */ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Callbacks, TaskStackChangeListener { @@ -140,9 +138,9 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca @Inject public ImmersiveModeConfirmation(Context context, CommandQueue commandQueue, - SecureSettings secureSettings, - dagger.Lazy<ViewCapture> daggerLazyViewCapture, - @Background Handler backgroundHandler) { + SecureSettings secureSettings, + dagger.Lazy<ViewCapture> daggerLazyViewCapture, + @Background Handler backgroundHandler) { mSysUiContext = context; final Display display = mSysUiContext.getDisplay(); mDisplayContext = display.getDisplayId() == DEFAULT_DISPLAY @@ -213,7 +211,7 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca public void immersiveModeChanged(int rootDisplayAreaId, boolean isImmersiveMode) { mHandler.removeMessages(H.SHOW); if (isImmersiveMode) { - if (DEBUG) Log.d(TAG, "immersiveModeChanged() sConfirmed=" + sConfirmed); + if (DEBUG) Log.d(TAG, "immersiveModeChanged() sConfirmed=" + sConfirmed); boolean userSetupComplete = (mSecureSettings.getIntForUser( Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0); @@ -314,44 +312,42 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca @Override public void start() { - if (CLIENT_TRANSIENT || CLIENT_IMMERSIVE_CONFIRMATION) { - mCommandQueue.addCallback(this); - - final Resources r = mSysUiContext.getResources(); - mShowDelayMs = r.getInteger(R.integer.dock_enter_exit_duration) * 3L; - mCanSystemBarsBeShownByUser = !r.getBoolean( - R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean( - R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction); - IVrManager vrManager = IVrManager.Stub.asInterface( - ServiceManager.getService(Context.VR_SERVICE)); - if (vrManager != null) { - try { - mVrModeEnabled = vrManager.getVrModeState(); - vrManager.registerListener(mVrStateCallbacks); - mVrStateCallbacks.onVrStateChanged(mVrModeEnabled); - } catch (RemoteException e) { - // Ignore, we cannot do anything if we failed to access vr manager. - } - } - TaskStackChangeListeners.getInstance().registerTaskStackListener(this); - mContentObserver = new ContentObserver(mBackgroundHandler) { - @Override - public void onChange(boolean selfChange) { - onSettingChanged(mSysUiContext.getUserId()); - } - }; + mCommandQueue.addCallback(this); - // Register to listen for changes in Settings.Secure settings. - mSecureSettings.registerContentObserverForUserSync( - Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS, mContentObserver, - UserHandle.USER_CURRENT); - mSecureSettings.registerContentObserverForUserSync( - Settings.Secure.USER_SETUP_COMPLETE, mContentObserver, - UserHandle.USER_CURRENT); - mBackgroundHandler.post(() -> { - loadSetting(UserHandle.USER_CURRENT); - }); + final Resources r = mSysUiContext.getResources(); + mShowDelayMs = r.getInteger(R.integer.dock_enter_exit_duration) * 3L; + mCanSystemBarsBeShownByUser = !r.getBoolean( + R.bool.config_remoteInsetsControllerControlsSystemBars) || r.getBoolean( + R.bool.config_remoteInsetsControllerSystemBarsCanBeShownByUserAction); + IVrManager vrManager = IVrManager.Stub.asInterface( + ServiceManager.getService(Context.VR_SERVICE)); + if (vrManager != null) { + try { + mVrModeEnabled = vrManager.getVrModeState(); + vrManager.registerListener(mVrStateCallbacks); + mVrStateCallbacks.onVrStateChanged(mVrModeEnabled); + } catch (RemoteException e) { + // Ignore, we cannot do anything if we failed to access vr manager. + } } + TaskStackChangeListeners.getInstance().registerTaskStackListener(this); + mContentObserver = new ContentObserver(mBackgroundHandler) { + @Override + public void onChange(boolean selfChange) { + onSettingChanged(mSysUiContext.getUserId()); + } + }; + + // Register to listen for changes in Settings.Secure settings. + mSecureSettings.registerContentObserverForUserSync( + Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS, mContentObserver, + UserHandle.USER_CURRENT); + mSecureSettings.registerContentObserverForUserSync( + Settings.Secure.USER_SETUP_COMPLETE, mContentObserver, + UserHandle.USER_CURRENT); + mBackgroundHandler.post(() -> { + loadSetting(UserHandle.USER_CURRENT); + }); } private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @@ -542,7 +538,7 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca /** * Returns options that specify the {@link RootDisplayArea} to attach the confirmation window. - * {@code null} if the {@code rootDisplayAreaId} is {@link FEATURE_UNDEFINED}. + * {@code null} if the {@code rootDisplayAreaId} is {@link FEATURE_UNDEFINED}. */ @Nullable private Bundle getOptionsForWindowContext(int rootDisplayAreaId) { @@ -600,10 +596,7 @@ public class ImmersiveModeConfirmation implements CoreStartable, CommandQueue.Ca @Override public void handleMessage(Message msg) { - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - return; - } - switch(msg.what) { + switch (msg.what) { case SHOW: handleShow(msg.arg1); break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index 2ed168aa82e8..2157d754ce87 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -486,11 +486,6 @@ public final class KeyboardShortcuts { R.string.keyboard_shortcut_group_system_shortcuts_helper), KeyEvent.KEYCODE_SLASH, KeyEvent.META_META_ON)); - systemGroup.addItem(new KeyboardShortcutInfo( - mContext.getString( - R.string.keyboard_shortcut_group_system_switch_input), - KeyEvent.KEYCODE_SPACE, - KeyEvent.META_META_ON)); return systemGroup; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt index 38f7c39203f0..ca2fbdd1cdd9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt @@ -34,6 +34,7 @@ import androidx.dynamicanimation.animation.SpringForce import com.android.app.animation.Interpolators import com.android.app.tracing.coroutines.TrackTracer import com.android.systemui.Dumpable +import com.android.systemui.Flags import com.android.systemui.Flags.spatialModelAppPushback import com.android.systemui.animation.ShadeInterpolation import com.android.systemui.dagger.SysUISingleton @@ -52,8 +53,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.SplitShadeStateController import com.android.systemui.util.WallpaperController import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor -import com.android.systemui.window.flag.WindowBlurFlag import com.android.wm.shell.appzoomout.AppZoomOut + import java.io.PrintWriter import java.util.Optional import javax.inject.Inject @@ -230,7 +231,7 @@ constructor( val zoomOut = blurRadiusToZoomOut(blurRadius = shadeRadius) // Make blur be 0 if it is necessary to stop blur effect. if (scrimsVisible) { - if (!WindowBlurFlag.isEnabled) { + if (!Flags.notificationShadeBlur()) { blur = 0 } } @@ -258,7 +259,9 @@ constructor( } private val shouldBlurBeOpaque: Boolean - get() = if (WindowBlurFlag.isEnabled) false else scrimsVisible && !blursDisabledForAppLaunch + get() = + if (Flags.notificationShadeBlur()) false + else scrimsVisible && !blursDisabledForAppLaunch /** Callback that updates the window blur value and is called only once per frame. */ @VisibleForTesting @@ -388,7 +391,7 @@ constructor( } private fun initBlurListeners() { - if (!WindowBlurFlag.isEnabled) return + if (!Flags.bouncerUiRevamp()) return applicationScope.launch { Log.d(TAG, "Starting coroutines for window root view blur") @@ -523,7 +526,7 @@ constructor( private fun scheduleUpdate() { val (blur, zoomOutFromShadeRadius) = computeBlurAndZoomOut() zoomOutCalculatedFromShadeRadius = zoomOutFromShadeRadius - if (WindowBlurFlag.isEnabled) { + if (Flags.bouncerUiRevamp()) { updateScheduled = windowRootViewBlurInteractor.requestBlurForShade(blur, shouldBlurBeOpaque) return diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS index 72b03bfa20c3..b2764e1a2302 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS +++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS @@ -16,6 +16,12 @@ per-file *Keyguard* = set noparent per-file *Keyguard* = file:../keyguard/OWNERS # Not setting noparent here, since *Notification* also matches some status bar notification chips files (statusbar/chips/notification) which should be owned by the status bar team. per-file *Notification* = file:notification/OWNERS +# Files that control blur effects on shade +per-file *NotificationShadeDepth* = set noparent +per-file *NotificationShadeDepth* = shanh@google.com, rahulbanerjee@google.com +per-file *NotificationShadeDepth* = file:../keyguard/OWNERS +per-file *Blur* = set noparent +per-file *Blur* = shanh@google.com, rahulbanerjee@google.com # Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*) per-file *Mode* = file:notification/OWNERS per-file *RemoteInput* = set noparent diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt index 86954d569199..108d737e7658 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt @@ -30,7 +30,9 @@ import com.android.systemui.res.R import com.android.systemui.statusbar.chips.StatusBarChipLogTags.pad import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor +import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.chips.ui.model.ColorsModel +import com.android.systemui.statusbar.chips.ui.model.ColorsModel.Companion.toCustomColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel @@ -76,14 +78,24 @@ constructor( OngoingActivityChipModel.ChipIcon.SingleColorIcon(phoneIcon) } + val colors = + if (StatusBarNotifChips.isEnabled && state.promotedContent != null) { + state.promotedContent.toCustomColorsModel() + } else { + ColorsModel.Themed + } + // This block mimics OngoingCallController#updateChip. if (state.startTimeMs <= 0L) { // If the start time is invalid, don't show a timer and show just an // icon. See b/192379214. OngoingActivityChipModel.Shown.IconOnly( icon = icon, - colors = ColorsModel.Themed, - getOnClickListener(state), + colors = colors, + onClickListenerLegacy = getOnClickListener(state), + // TODO(b/372657935): Add click support for the call chip when + // StatusBarChipModernization is enabled. + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) } else { val startTimeInElapsedRealtime = @@ -91,9 +103,12 @@ constructor( systemClock.elapsedRealtime() OngoingActivityChipModel.Shown.Timer( icon = icon, - colors = ColorsModel.Themed, + colors = colors, startTimeMs = startTimeInElapsedRealtime, - getOnClickListener(state), + onClickListenerLegacy = getOnClickListener(state), + // TODO(b/372657935): Add click support for the call chip when + // StatusBarChipModernization is enabled. + clickBehavior = OngoingActivityChipModel.ClickBehavior.None, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt index 3422337523f9..baa8eec5f767 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.viewmodel.ChipTransitionHelper import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel +import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickCallback import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -204,13 +205,25 @@ constructor( colors = ColorsModel.Red, // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time. startTimeMs = systemClock.elapsedRealtime(), - createDialogLaunchOnClickListener( - createCastScreenToOtherDeviceDialogDelegate(state), - dialogTransitionAnimator, - DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Cast to other device"), - logger, - TAG, - ), + onClickListenerLegacy = + createDialogLaunchOnClickListener( + createCastScreenToOtherDeviceDialogDelegate(state), + dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ), + clickBehavior = + OngoingActivityChipModel.ClickBehavior.ExpandAction( + onClick = + createDialogLaunchOnClickCallback( + createCastScreenToOtherDeviceDialogDelegate(state), + dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ) + ), ) } @@ -225,16 +238,24 @@ constructor( ) ), colors = ColorsModel.Red, - createDialogLaunchOnClickListener( - createGenericCastToOtherDeviceDialogDelegate(deviceName), - dialogTransitionAnimator, - DialogCuj( - Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, - tag = "Cast to other device audio only", + onClickListenerLegacy = + createDialogLaunchOnClickListener( + createGenericCastToOtherDeviceDialogDelegate(deviceName), + dialogTransitionAnimator, + DIALOG_CUJ_AUDIO_ONLY, + logger, + TAG, + ), + clickBehavior = + OngoingActivityChipModel.ClickBehavior.ExpandAction( + createDialogLaunchOnClickCallback( + createGenericCastToOtherDeviceDialogDelegate(deviceName), + dialogTransitionAnimator, + DIALOG_CUJ_AUDIO_ONLY, + logger, + TAG, + ) ), - logger, - TAG, - ), ) } @@ -256,6 +277,13 @@ constructor( companion object { @DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected + private val DIALOG_CUJ = + DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Cast to other device") + private val DIALOG_CUJ_AUDIO_ONLY = + DialogCuj( + Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, + tag = "Cast to other device audio only", + ) private val TAG = "CastToOtherVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt index 2121f94caced..4fad01d9f448 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/domain/interactor/StatusBarNotificationChipsInteractor.kt @@ -28,6 +28,7 @@ import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor +import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor.Companion.isOngoingCallNotification import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -41,6 +42,7 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map /** An interactor for the notification chips shown in the status bar. */ @SysUISingleton @@ -88,45 +90,56 @@ constructor( private val promotedNotificationInteractors = MutableStateFlow<List<SingleNotificationChipInteractor>>(emptyList()) + /** + * The notifications that are promoted and ongoing. + * + * Explicitly does *not* include any ongoing call notifications, even if the call notifications + * meet the promotion criteria. Those call notifications will be handled by + * [com.android.systemui.statusbar.chips.call.domain.CallChipInteractor] instead. See + * b/388521980. + */ + private val promotedOngoingNotifications = + activeNotificationsInteractor.promotedOngoingNotifications.map { notifs -> + notifs.filterNot { it.isOngoingCallNotification() } + } + override fun start() { if (!StatusBarNotifChips.isEnabled) { return } backgroundScope.launch("StatusBarNotificationChipsInteractor") { - activeNotificationsInteractor.promotedOngoingNotifications - .pairwise(initialValue = emptyList()) - .collect { (oldNotifs, currentNotifs) -> - val removedNotifKeys = - oldNotifs.map { it.key }.minus(currentNotifs.map { it.key }.toSet()) - removedNotifKeys.forEach { removedNotifKey -> - val wasRemoved = promotedNotificationInteractorMap.remove(removedNotifKey) - if (wasRemoved == null) { - logger.w({ - "Attempted to remove $str1 from interactor map but it wasn't present" - }) { - str1 = removedNotifKey - } + promotedOngoingNotifications.pairwise(initialValue = emptyList()).collect { + (oldNotifs, currentNotifs) -> + val removedNotifKeys = + oldNotifs.map { it.key }.minus(currentNotifs.map { it.key }.toSet()) + removedNotifKeys.forEach { removedNotifKey -> + val wasRemoved = promotedNotificationInteractorMap.remove(removedNotifKey) + if (wasRemoved == null) { + logger.w({ + "Attempted to remove $str1 from interactor map but it wasn't present" + }) { + str1 = removedNotifKey } } + } - currentNotifs.forEach { notif -> - val interactor = - promotedNotificationInteractorMap.computeIfAbsent(notif.key) { - singleNotificationChipInteractorFactory.create( - notif, - creationTime = systemClock.currentTimeMillis(), - ) - } - interactor.setNotification(notif) - } - logger.d({ "Interactors: $str1" }) { - str1 = - promotedNotificationInteractorMap.keys.joinToString(separator = " /// ") - } - promotedNotificationInteractors.value = - promotedNotificationInteractorMap.values.toList() + currentNotifs.forEach { notif -> + val interactor = + promotedNotificationInteractorMap.computeIfAbsent(notif.key) { + singleNotificationChipInteractorFactory.create( + notif, + creationTime = systemClock.currentTimeMillis(), + ) + } + interactor.setNotification(notif) } + logger.d({ "Interactors: $str1" }) { + str1 = promotedNotificationInteractorMap.keys.joinToString(separator = " /// ") + } + promotedNotificationInteractors.value = + promotedNotificationInteractorMap.values.toList() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt index ec3a5b271e35..b7cad625b7b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/notification/ui/viewmodel/NotifChipsViewModel.kt @@ -23,7 +23,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.chips.notification.domain.interactor.StatusBarNotificationChipsInteractor import com.android.systemui.statusbar.chips.notification.domain.model.NotificationChipModel import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips -import com.android.systemui.statusbar.chips.ui.model.ColorsModel +import com.android.systemui.statusbar.chips.ui.model.ColorsModel.Companion.toCustomColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.core.StatusBarConnectedDisplays import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor @@ -72,11 +72,7 @@ constructor( StatusBarConnectedDisplays.assertInNewMode() OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon(this.key) } - val colors = - ColorsModel.Custom( - backgroundColorInt = this.promotedContent.colors.backgroundColor, - primaryTextColorInt = this.promotedContent.colors.primaryTextColor, - ) + val colors = this.promotedContent.toCustomColorsModel() val onClickListener = View.OnClickListener { // The notification pipeline needs everything to run on the main thread, so keep @@ -87,6 +83,7 @@ constructor( ) } } + val clickBehavior = OngoingActivityChipModel.ClickBehavior.None val isShowingHeadsUpFromChipTap = headsUpState is TopPinnedState.Pinned && @@ -95,7 +92,12 @@ constructor( if (isShowingHeadsUpFromChipTap) { // If the user tapped this chip to show the HUN, we want to just show the icon because // the HUN will show the rest of the information. - return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener) + return OngoingActivityChipModel.Shown.IconOnly( + icon, + colors, + onClickListener, + clickBehavior, + ) } if (this.promotedContent.shortCriticalText != null) { @@ -104,6 +106,7 @@ constructor( colors, this.promotedContent.shortCriticalText, onClickListener, + clickBehavior, ) } @@ -115,11 +118,21 @@ constructor( // notification will likely just be set to the current time, which would cause the chip // to always show "now". We don't want early testers to get that experience since it's // not what will happen at launch, so just don't show any time. - return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener) + return OngoingActivityChipModel.Shown.IconOnly( + icon, + colors, + onClickListener, + clickBehavior, + ) } if (this.promotedContent.time == null) { - return OngoingActivityChipModel.Shown.IconOnly(icon, colors, onClickListener) + return OngoingActivityChipModel.Shown.IconOnly( + icon, + colors, + onClickListener, + clickBehavior, + ) } when (this.promotedContent.time.mode) { PromotedNotificationContentModel.When.Mode.BasicTime -> { @@ -128,6 +141,7 @@ constructor( colors, time = this.promotedContent.time.time, onClickListener, + clickBehavior, ) } PromotedNotificationContentModel.When.Mode.CountUp -> { @@ -136,6 +150,7 @@ constructor( colors, startTimeMs = this.promotedContent.time.time, onClickListener, + clickBehavior, ) } PromotedNotificationContentModel.When.Mode.CountDown -> { @@ -145,6 +160,7 @@ constructor( colors, startTimeMs = this.promotedContent.time.time, onClickListener, + clickBehavior, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt index 0065593c7b73..7f2327a742e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt @@ -41,6 +41,7 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.viewmodel.ChipTransitionHelper import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel +import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickCallback import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.time.SystemClock @@ -91,16 +92,24 @@ constructor( ), colors = ColorsModel.Red, startTimeMs = systemClock.elapsedRealtime(), - createDialogLaunchOnClickListener( - createDelegate(state.recordedTask), - dialogTransitionAnimator, - DialogCuj( - Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, - tag = "Screen record", + onClickListenerLegacy = + createDialogLaunchOnClickListener( + createDelegate(state.recordedTask), + dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ), + clickBehavior = + OngoingActivityChipModel.ClickBehavior.ExpandAction( + createDialogLaunchOnClickCallback( + dialogDelegate = createDelegate(state.recordedTask), + dialogTransitionAnimator = dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ) ), - logger, - TAG, - ), ) } } @@ -154,6 +163,8 @@ constructor( companion object { @DrawableRes val ICON = R.drawable.ic_screenrecord + private val DIALOG_CUJ = + DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Screen record") private val TAG = "ScreenRecordVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt index 2af86a51cf70..6654d4a8f104 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.viewmodel.ChipTransitionHelper import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel +import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickCallback import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener import com.android.systemui.util.time.SystemClock import javax.inject.Inject @@ -128,13 +129,25 @@ constructor( colors = ColorsModel.Red, // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time. startTimeMs = systemClock.elapsedRealtime(), - createDialogLaunchOnClickListener( - createShareScreenToAppDialogDelegate(state), - dialogTransitionAnimator, - DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Share to app"), - logger, - TAG, - ), + onClickListenerLegacy = + createDialogLaunchOnClickListener( + createShareScreenToAppDialogDelegate(state), + dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ), + clickBehavior = + OngoingActivityChipModel.ClickBehavior.ExpandAction( + onClick = + createDialogLaunchOnClickCallback( + createShareScreenToAppDialogDelegate(state), + dialogTransitionAnimator, + DIALOG_CUJ, + logger, + TAG, + ) + ), ) } @@ -150,16 +163,24 @@ constructor( ) ), colors = ColorsModel.Red, - createDialogLaunchOnClickListener( - createGenericShareToAppDialogDelegate(), - dialogTransitionAnimator, - DialogCuj( - Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, - tag = "Share to app audio only", + onClickListenerLegacy = + createDialogLaunchOnClickListener( + createGenericShareToAppDialogDelegate(), + dialogTransitionAnimator, + DIALOG_CUJ_AUDIO_ONLY, + logger, + TAG, + ), + clickBehavior = + OngoingActivityChipModel.ClickBehavior.ExpandAction( + createDialogLaunchOnClickCallback( + createGenericShareToAppDialogDelegate(), + dialogTransitionAnimator, + DIALOG_CUJ_AUDIO_ONLY, + logger, + TAG, + ) ), - logger, - TAG, - ), ) } @@ -180,6 +201,10 @@ constructor( companion object { @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_present_to_all + private val DIALOG_CUJ = + DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Share to app") + private val DIALOG_CUJ_AUDIO_ONLY = + DialogCuj(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP, tag = "Share to app audio only") private val TAG = "ShareToAppVM".pad() } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt index b0fa9d842480..d46638fac46c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/binder/OngoingActivityChipBinder.kt @@ -56,7 +56,8 @@ object OngoingActivityChipBinder { // Data setChipIcon(chipModel, chipBackgroundView, chipDefaultIconView, iconViewStore) setChipMainContent(chipModel, chipTextView, chipTimeView, chipShortTimeDeltaView) - viewBinding.rootView.setOnClickListener(chipModel.onClickListener) + + viewBinding.rootView.setOnClickListener(chipModel.onClickListenerLegacy) updateChipPadding( chipModel, chipBackgroundView, @@ -424,7 +425,7 @@ object OngoingActivityChipBinder { // Clickable chips need to be a minimum size for accessibility purposes, but let // non-clickable chips be smaller. val minimumWidth = - if (chipModel.onClickListener != null) { + if (chipModel.onClickListenerLegacy != null) { chipBackgroundView.context.resources.getDimensionPixelSize( R.dimen.min_clickable_item_size ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt index 1be5842bceeb..6ce3228531d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt @@ -35,10 +35,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView +import com.android.compose.animation.Expandable +import com.android.systemui.animation.Expandable import com.android.systemui.common.ui.compose.Icon import com.android.systemui.res.R import com.android.systemui.statusbar.chips.ui.compose.modifiers.neverDecreaseWidth @@ -47,23 +50,42 @@ import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel @Composable fun OngoingActivityChip(model: OngoingActivityChipModel.Shown, modifier: Modifier = Modifier) { + when (val clickBehavior = model.clickBehavior) { + is OngoingActivityChipModel.ClickBehavior.ExpandAction -> { + // Wrap the chip in an Expandable so we can animate the expand transition. + ExpandableChip( + color = { Color.Transparent }, + shape = + RoundedCornerShape( + dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius) + ), + modifier = modifier, + ) { expandable -> + ChipBody(model, onClick = { clickBehavior.onClick(expandable) }) + } + } + + is OngoingActivityChipModel.ClickBehavior.None -> { + ChipBody(model, modifier = modifier) + } + } +} + +@Composable +private fun ChipBody( + model: OngoingActivityChipModel.Shown, + modifier: Modifier = Modifier, + onClick: () -> Unit = {}, +) { val context = LocalContext.current - val isClickable = model.onClickListener != null + val isClickable = onClick != {} val hasEmbeddedIcon = model.icon is OngoingActivityChipModel.ChipIcon.StatusBarView // Use a Box with `fillMaxHeight` to create a larger click surface for the chip. The visible // height of the chip is determined by the height of the background of the Row below. Box( contentAlignment = Alignment.Center, - modifier = - modifier - .fillMaxHeight() - .clickable( - enabled = isClickable, - onClick = { - // TODO(b/372657935): Implement click actions. - }, - ), + modifier = modifier.fillMaxHeight().clickable(enabled = isClickable, onClick = onClick), ) { Row( horizontalArrangement = Arrangement.Center, @@ -206,3 +228,13 @@ private fun ChipContent(viewModel: OngoingActivityChipModel.Shown, modifier: Mod } } } + +@Composable +private fun ExpandableChip( + color: () -> Color, + shape: Shape, + modifier: Modifier = Modifier, + content: @Composable (Expandable) -> Unit, +) { + Expandable(color = color(), shape = shape, modifier = modifier.clip(shape)) { content(it) } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt index cac25d04f1a5..25f90f9a0065 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt @@ -21,6 +21,7 @@ import android.content.res.ColorStateList import androidx.annotation.ColorInt import com.android.settingslib.Utils import com.android.systemui.res.R +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel /** Model representing how the chip in the status bar should be colored. */ sealed interface ColorsModel { @@ -55,4 +56,14 @@ sealed interface ColorsModel { override fun text(context: Context) = context.getColor(android.R.color.white) } + + companion object { + /** Converts the promoted notification colors to a [Custom] colors model. */ + fun PromotedNotificationContentModel.toCustomColorsModel(): Custom { + return Custom( + backgroundColorInt = this.colors.backgroundColor, + primaryTextColorInt = this.colors.primaryTextColor, + ) + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt index 956d99e46766..68c8f8cb4254 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.chips.ui.model import android.view.View +import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.Icon import com.android.systemui.statusbar.StatusBarIconView import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips @@ -46,17 +47,20 @@ sealed class OngoingActivityChipModel { open val colors: ColorsModel, /** * Listener method to invoke when this chip is clicked. If null, the chip won't be - * clickable. + * clickable. Will be deprecated after [StatusBarChipsModernization] is enabled. */ - open val onClickListener: View.OnClickListener?, + open val onClickListenerLegacy: View.OnClickListener?, + /** Data class that determines how clicks on the chip should be handled. */ + open val clickBehavior: ClickBehavior, ) : OngoingActivityChipModel() { /** This chip shows only an icon and nothing else. */ data class IconOnly( override val icon: ChipIcon, override val colors: ColorsModel, - override val onClickListener: View.OnClickListener?, - ) : Shown(icon, colors, onClickListener) { + override val onClickListenerLegacy: View.OnClickListener?, + override val clickBehavior: ClickBehavior, + ) : Shown(icon, colors, onClickListenerLegacy, clickBehavior) { override val logName = "Shown.Icon" } @@ -74,8 +78,9 @@ sealed class OngoingActivityChipModel { * [android.widget.Chronometer.setBase]. */ val startTimeMs: Long, - override val onClickListener: View.OnClickListener?, - ) : Shown(icon, colors, onClickListener) { + override val onClickListenerLegacy: View.OnClickListener?, + override val clickBehavior: ClickBehavior, + ) : Shown(icon, colors, onClickListenerLegacy, clickBehavior) { override val logName = "Shown.Timer" } @@ -88,8 +93,9 @@ sealed class OngoingActivityChipModel { override val colors: ColorsModel, /** The time of the event that this chip represents. */ val time: Long, - override val onClickListener: View.OnClickListener?, - ) : Shown(icon, colors, onClickListener) { + override val onClickListenerLegacy: View.OnClickListener?, + override val clickBehavior: ClickBehavior, + ) : Shown(icon, colors, onClickListenerLegacy, clickBehavior) { init { StatusBarNotifChips.assertInNewMode() } @@ -105,7 +111,13 @@ sealed class OngoingActivityChipModel { override val colors: ColorsModel, /** The number of seconds until an event is started. */ val secondsUntilStarted: Long, - ) : Shown(icon = null, colors, onClickListener = null) { + ) : + Shown( + icon = null, + colors, + onClickListenerLegacy = null, + clickBehavior = ClickBehavior.None, + ) { override val logName = "Shown.Countdown" } @@ -115,8 +127,9 @@ sealed class OngoingActivityChipModel { override val colors: ColorsModel, // TODO(b/361346412): Enforce a max length requirement? val text: String, - override val onClickListener: View.OnClickListener? = null, - ) : Shown(icon, colors, onClickListener) { + override val onClickListenerLegacy: View.OnClickListener? = null, + override val clickBehavior: ClickBehavior, + ) : Shown(icon, colors, onClickListenerLegacy, clickBehavior) { override val logName = "Shown.Text" } } @@ -149,4 +162,13 @@ sealed class OngoingActivityChipModel { */ data class SingleColorIcon(val impl: Icon) : ChipIcon } + + /** Defines the behavior of the chip when it is clicked. */ + sealed interface ClickBehavior { + /** No specific click behavior. */ + data object None : ClickBehavior + + /** The chip expands into a dialog or activity on click. */ + data class ExpandAction(val onClick: (Expandable) -> Unit) : ClickBehavior + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt index 2fc366b7f078..a978c04d2a2e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.chips.ui.viewmodel import android.view.View import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator +import com.android.systemui.animation.Expandable import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel import com.android.systemui.res.R @@ -26,6 +27,7 @@ import com.android.systemui.statusbar.chips.StatusBarChipsLog import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization import kotlinx.coroutines.flow.StateFlow /** @@ -46,6 +48,7 @@ interface OngoingActivityChipViewModel { tag: String, ): View.OnClickListener { return View.OnClickListener { view -> + StatusBarChipsModernization.assertInLegacyMode() logger.log(tag, LogLevel.INFO, {}, { "Chip clicked" }) val dialog = dialogDelegate.createDialog() val launchableView = @@ -55,5 +58,28 @@ interface OngoingActivityChipViewModel { dialogTransitionAnimator.showFromView(dialog, launchableView, cuj) } } + + /** + * Creates a chip click callback with an [Expandable] parameter that launches a dialog + * created by [dialogDelegate]. + */ + fun createDialogLaunchOnClickCallback( + dialogDelegate: SystemUIDialog.Delegate, + dialogTransitionAnimator: DialogTransitionAnimator, + cuj: DialogCuj, + @StatusBarChipsLog logger: LogBuffer, + tag: String, + ): (Expandable) -> Unit { + return { expandable -> + StatusBarChipsModernization.assertInNewMode() + logger.log(tag, LogLevel.INFO, {}, { "Chip clicked" }) + val dialog = dialogDelegate.createDialog() + + val controller = expandable.dialogTransitionController(cuj) + if (controller != null) { + dialogTransitionAnimator.show(dialog, controller) + } + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt new file mode 100644 index 000000000000..2ae54d7c6c83 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/headsup/shared/StatusBarNoHunBehavior.kt @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2025 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.headsup.shared + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the status bar no hun behavior flag state. */ +@Suppress("NOTHING_TO_INLINE") +object StatusBarNoHunBehavior { + /** The aconfig flag name */ + const val FLAG_NAME = Flags.FLAG_STATUS_BAR_NO_HUN_BEHAVIOR + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the refactor enabled */ + @JvmStatic + inline val isEnabled + get() = Flags.statusBarNoHunBehavior() && android.app.Flags.notificationsRedesignAppIcons() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is enabled. This will throw an exception if + * the flag is not enabled to ensure that the refactor author catches issues in testing. + * Caution!! Using this check incorrectly will cause crashes in nextfood builds! + */ + @JvmStatic + inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index c38b84b710bc..417e57d2205f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -34,6 +34,8 @@ import static com.android.systemui.statusbar.notification.stack.NotificationPrio import static java.util.Objects.requireNonNull; +import android.annotation.FlaggedApi; +import android.app.Flags; import android.app.Notification; import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; @@ -1091,6 +1093,14 @@ public final class NotificationEntry extends ListEntry { } /** + * Returns whether the NotificationEntry is promoted ongoing. + */ + @FlaggedApi(Flags.FLAG_API_RICH_ONGOING) + public boolean isPromotedOngoing() { + return PromotedNotificationContentModel.isPromotedForStatusBarChip(mSbn.getNotification()); + } + + /** * Sets the content needed to render this notification as a promoted notification on various * surfaces (like status bar chips and AOD). */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt new file mode 100644 index 000000000000..629cb831f17a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StabilizeHeadsUpGroup.kt @@ -0,0 +1,61 @@ +/* + * 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.notification.collection.coordinator + +import com.android.systemui.Flags +import com.android.systemui.flags.FlagToken +import com.android.systemui.flags.RefactorFlagUtils + +/** Helper for reading or using the every change not allowed in heads up Group mode flag state. */ +@Suppress("NOTHING_TO_INLINE") +object StabilizeHeadsUpGroup { + /** The aconfig flag name */ + const val FLAG_NAME: String = Flags.FLAG_STABILIZE_HEADS_UP_GROUP + + /** A token used for dependency declaration */ + val token: FlagToken + get() = FlagToken(FLAG_NAME, isEnabled) + + /** Is the refactor enabled */ + @JvmStatic + inline val isEnabled + get() = Flags.stabilizeHeadsUpGroup() + + /** + * Called to ensure code is only run when the flag is enabled. This protects users from the + * unintended behaviors caused by accidentally running new logic, while also crashing on an eng + * build to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun isUnexpectedlyInLegacyMode() = + RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is enabled. This will throw an exception if + * the flag is not enabled to ensure that the refactor author catches issues in testing. + * Caution!! Using this check incorrectly will cause crashes in nextfood builds! + */ + @JvmStatic + inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME) + + /** + * Called to ensure code is only run when the flag is disabled. This will throw an exception if + * the flag is enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java index 3c31d893cf72..49d5029bbc70 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java @@ -26,6 +26,7 @@ import com.android.systemui.Flags; import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; @@ -41,11 +42,12 @@ import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener; import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager; import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor; -import com.android.systemui.statusbar.notification.shared.NotificationMinimalism; import com.android.systemui.statusbar.notification.headsup.HeadsUpManager; +import com.android.systemui.statusbar.notification.shared.NotificationMinimalism; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.kotlin.BooleanFlowOperators; @@ -54,6 +56,7 @@ import com.android.systemui.util.kotlin.JavaAdapter; import java.io.PrintWriter; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -68,6 +71,7 @@ import javax.inject.Inject; @SysUISingleton public class VisualStabilityCoordinator implements Coordinator, Dumpable { private final DelayableExecutor mDelayableExecutor; + private final DelayableExecutor mMainExecutor; private final HeadsUpManager mHeadsUpManager; private final SeenNotificationsInteractor mSeenNotificationsInteractor; private final ShadeAnimationInteractor mShadeAnimationInteractor; @@ -91,6 +95,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { private boolean mCommunalShowing = false; private boolean mLockscreenShowing = false; private boolean mLockscreenInGoneTransition = false; + private Set<String> mHeadsUpGroupKeys = new HashSet<>(); private boolean mPipelineRunAllowed; private boolean mReorderingAllowed; @@ -110,6 +115,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { @Inject public VisualStabilityCoordinator( @Background DelayableExecutor delayableExecutor, + @Main DelayableExecutor mainExecutor, DumpManager dumpManager, HeadsUpManager headsUpManager, ShadeAnimationInteractor shadeAnimationInteractor, @@ -133,6 +139,7 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; mDelayableExecutor = delayableExecutor; + mMainExecutor = mainExecutor; mCommunalSceneInteractor = communalSceneInteractor; mShadeInteractor = shadeInteractor; mKeyguardTransitionInteractor = keyguardTransitionInteractor; @@ -161,6 +168,11 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { ), this::onCommunalShowingChanged); + + if (StabilizeHeadsUpGroup.isEnabled()) { + pipeline.addOnBeforeRenderListListener(mOnBeforeRenderListListener); + } + if (SceneContainerFlag.isEnabled()) { mJavaAdapter.alwaysCollectFlow(mKeyguardTransitionInteractor.transitionValue( KeyguardState.LOCKSCREEN), @@ -176,10 +188,37 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { mKeyguardStateController.addCallback(mKeyguardFadeAwayAnimationCallback); } } - pipeline.setVisualStabilityManager(mNotifStabilityManager); } + /** + * Setter of heads up group keys. + */ + @VisibleForTesting + public void setHeadsUpGroupKeys(Set<String> currentHeadsUpGroupKeys) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return; + } + + if (currentHeadsUpGroupKeys == null) { + currentHeadsUpGroupKeys = new HashSet<>(); + } + + boolean isAnyHeadsUpGroupRemoved = false; + for (String headsUpKey: mHeadsUpGroupKeys) { + if (!currentHeadsUpGroupKeys.contains(headsUpKey)) { + isAnyHeadsUpGroupRemoved = true; + break; + } + } + mHeadsUpGroupKeys = currentHeadsUpGroupKeys; + + if (isAnyHeadsUpGroupRemoved) { + updateAllowedStates("headsUpGroupEntryChange", + mHeadsUpGroupKeys.isEmpty(), /* async= */ true); + } + } + final KeyguardStateController.Callback mKeyguardFadeAwayAnimationCallback = new KeyguardStateController.Callback() { @Override @@ -206,6 +245,64 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { return false; } + private boolean isParentHeadsUpGroup(NotificationEntry entry) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return false; + } + if (entry == null) { + return false; + } + + final GroupEntry parent = entry.getParent(); + + if (parent == null) { + return false; + } + + return isHeadsUpGroup(parent); + } + + private boolean isHeadsUpGroup(GroupEntry groupEntry) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return false; + } + + if (groupEntry == null) { + return false; + } + + final NotificationEntry summary = groupEntry.getSummary(); + if (summary == null) { + return false; + } + + return mHeadsUpManager.isHeadsUpEntry(summary.getKey()); + } + /** + * When reordering is enabled, non-heads-up groups can be pruned. + * @return true if the given group entry can be pruned. + */ + private boolean canReorderGroupEntry(GroupEntry entry) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return false; + } + + return entry != null && mReorderingAllowed && !isHeadsUpGroup(entry); + } + + /** + * When reordering is enabled, notifications in non-heads-up groups notifications + * are allowed to change. + * @return true if the given notification entry can changed. + */ + private boolean canReorderNotificationEntry(NotificationEntry entry) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return false; + } + + return entry != null && mReorderingAllowed && !isParentHeadsUpGroup(entry); + } + @Override public void onBeginRun() { mIsSuppressingPipelineRun = false; @@ -222,25 +319,50 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { @Override public boolean isGroupChangeAllowed(@NonNull NotificationEntry entry) { - final boolean isGroupChangeAllowedForEntry = - mReorderingAllowed || canMoveForHeadsUp(entry); + final boolean isGroupChangeAllowedForEntry; + if (StabilizeHeadsUpGroup.isEnabled()) { + isGroupChangeAllowedForEntry = + isEveryChangeAllowed() + || canReorderNotificationEntry(entry) + || canMoveForHeadsUp(entry); + } else { + isGroupChangeAllowedForEntry = mReorderingAllowed + || canMoveForHeadsUp(entry); + } mIsSuppressingGroupChange |= !isGroupChangeAllowedForEntry; return isGroupChangeAllowedForEntry; } @Override public boolean isGroupPruneAllowed(@NonNull GroupEntry entry) { - final boolean isGroupPruneAllowedForEntry = mReorderingAllowed; + boolean isGroupPruneAllowedForEntry; + if (StabilizeHeadsUpGroup.isEnabled()) { + isGroupPruneAllowedForEntry = isEveryChangeAllowed() + || canReorderGroupEntry(entry); + } else { + isGroupPruneAllowedForEntry = mReorderingAllowed; + } + mIsSuppressingGroupChange |= !isGroupPruneAllowedForEntry; return isGroupPruneAllowedForEntry; } @Override public boolean isSectionChangeAllowed(@NonNull NotificationEntry entry) { - final boolean isSectionChangeAllowedForEntry = - mReorderingAllowed - || canMoveForHeadsUp(entry) - || mEntriesThatCanChangeSection.containsKey(entry.getKey()); + final boolean isSectionChangeAllowedForEntry; + if (StabilizeHeadsUpGroup.isEnabled()) { + isSectionChangeAllowedForEntry = + isEveryChangeAllowed() + || canReorderNotificationEntry(entry) + || canMoveForHeadsUp(entry) + || mEntriesThatCanChangeSection.containsKey(entry.getKey()); + } else { + isSectionChangeAllowedForEntry = + mReorderingAllowed + || canMoveForHeadsUp(entry) + || mEntriesThatCanChangeSection.containsKey(entry.getKey()); + } + if (!isSectionChangeAllowedForEntry) { mEntriesWithSuppressedSectionChange.add(entry.getKey()); } @@ -249,12 +371,27 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { @Override public boolean isEntryReorderingAllowed(@NonNull ListEntry entry) { - return mReorderingAllowed || canMoveForHeadsUp(entry.getRepresentativeEntry()); + if (StabilizeHeadsUpGroup.isEnabled()) { + if (isEveryChangeAllowed()) { + return true; + } + + final NotificationEntry notificationEntry = entry.getRepresentativeEntry(); + return canReorderNotificationEntry(notificationEntry) + || canMoveForHeadsUp(notificationEntry); + } else { + return mReorderingAllowed || canMoveForHeadsUp( + entry.getRepresentativeEntry()); + } } @Override public boolean isEveryChangeAllowed() { - return mReorderingAllowed; + if (StabilizeHeadsUpGroup.isEnabled()) { + return mReorderingAllowed && mHeadsUpGroupKeys.isEmpty(); + } else { + return mReorderingAllowed; + } } @Override @@ -263,7 +400,37 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { } }; + private final OnBeforeRenderListListener mOnBeforeRenderListListener = + new OnBeforeRenderListListener() { + @Override + public void onBeforeRenderList(List<ListEntry> entries) { + if (StabilizeHeadsUpGroup.isUnexpectedlyInLegacyMode()) { + return; + } + + final Set<String> currentHeadsUpKeys = new HashSet<>(); + + for (int i = 0; i < entries.size(); i++) { + if (entries.get(i) instanceof GroupEntry groupEntry) { + final NotificationEntry summary = groupEntry.getSummary(); + if (summary == null) continue; + + final String summaryKey = summary.getKey(); + if (mHeadsUpManager.isHeadsUpEntry(summaryKey)) { + currentHeadsUpKeys.add(summaryKey); + } + } + } + + setHeadsUpGroupKeys(currentHeadsUpKeys); + } + }; + private void updateAllowedStates(String field, boolean value) { + updateAllowedStates(field, value, /* async = */ false); + } + + private void updateAllowedStates(String field, boolean value, boolean async) { boolean wasPipelineRunAllowed = mPipelineRunAllowed; boolean wasReorderingAllowed = mReorderingAllowed; // No need to run notification pipeline when the lockscreen is in fading animation. @@ -275,20 +442,28 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { mLogger.logAllowancesChanged( wasPipelineRunAllowed, mPipelineRunAllowed, wasReorderingAllowed, mReorderingAllowed, - field, value); + field, value, async); } + if (async) { + mMainExecutor.execute(this::maybeInvalidateList); + } else { + maybeInvalidateList(); + } + mVisualStabilityProvider.setReorderingAllowed(mReorderingAllowed); + } + + private void maybeInvalidateList() { if (mPipelineRunAllowed && mIsSuppressingPipelineRun) { mNotifStabilityManager.invalidateList("pipeline run suppression ended"); } else if (mReorderingAllowed && (mIsSuppressingGroupChange || isSuppressingSectionChange() || mIsSuppressingEntryReorder)) { - String reason = "reorder suppression ended for" + final String reason = "reorder suppression ended for" + " group=" + mIsSuppressingGroupChange + " section=" + isSuppressingSectionChange() + " sort=" + mIsSuppressingEntryReorder; mNotifStabilityManager.invalidateList(reason); } - mVisualStabilityProvider.setReorderingAllowed(mReorderingAllowed); } private boolean isSuppressingSectionChange() { @@ -393,6 +568,9 @@ public class VisualStabilityCoordinator implements Coordinator, Dumpable { pw.println("isSuppressingPipelineRun: " + mIsSuppressingPipelineRun); pw.println("isSuppressingGroupChange: " + mIsSuppressingGroupChange); pw.println("isSuppressingEntryReorder: " + mIsSuppressingEntryReorder); + if (StabilizeHeadsUpGroup.isEnabled()) { + pw.println("headsUpGroupKeys: " + mHeadsUpGroupKeys.size()); + } pw.println("entriesWithSuppressedSectionChange: " + mEntriesWithSuppressedSectionChange.size()); for (String key : mEntriesWithSuppressedSectionChange) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorLogger.kt index fe23e4e12db4..5051afc53881 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorLogger.kt @@ -32,7 +32,8 @@ constructor(@VisualStabilityLog private val buffer: LogBuffer) { wasReorderingAllowed: Boolean, isReorderingAllowed: Boolean, field: String, - value: Boolean + value: Boolean, + async: Boolean, ) { buffer.log( TAG, @@ -44,13 +45,15 @@ constructor(@VisualStabilityLog private val buffer: LogBuffer) { bool4 = isReorderingAllowed str1 = field str2 = value.toString() + str3 = async.toString() }, { "stability allowances changed:" + " pipelineRunAllowed $bool1->$bool2" + " reorderingAllowed $bool3->$bool4" + " when setting $str1=$str2" - } + " async=$str3" + }, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index d83acf34ca99..9ed1632c8bc6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -248,8 +248,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { @NonNull NotifInflater.Params inflaterParams, ExpandableNotificationRow row, @Nullable NotificationRowContentBinder.InflationCallback inflationCallback) { - final boolean useIncreasedCollapsedHeight = - mMessagingUtil.isImportantMessaging(entry.getSbn(), entry.getImportance()); final boolean isMinimized = inflaterParams.isMinimized(); // Set show snooze action @@ -258,7 +256,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { RowContentBindParams params = mRowContentBindStage.getStageParams(entry); params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED); params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED); - params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight); params.setUseMinimized(isMinimized); int redactionType = inflaterParams.getRedactionType(); @@ -303,7 +300,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { mLogger.logRequestingRebind(entry, inflaterParams); mRowContentBindStage.requestRebind(entry, en -> { mLogger.logRebindComplete(entry); - row.setUsesIncreasedCollapsedHeight(useIncreasedCollapsedHeight); row.setIsMinimized(isMinimized); if (inflationCallback != null) { inflationCallback.onAsyncInflationFinished(en); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index ea48fb4ffd92..086c32cbae5d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -60,7 +60,6 @@ import com.android.systemui.statusbar.notification.collection.render.Notificatio import com.android.systemui.statusbar.notification.data.NotificationDataLayerModule; import com.android.systemui.statusbar.notification.domain.NotificationDomainLayerModule; import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor; -import com.android.systemui.statusbar.notification.footer.ui.viewmodel.FooterViewModelModule; import com.android.systemui.statusbar.notification.headsup.HeadsUpManager; import com.android.systemui.statusbar.notification.icon.ConversationIconManager; import com.android.systemui.statusbar.notification.icon.IconManager; @@ -109,7 +108,6 @@ import javax.inject.Provider; * Dagger Module for classes found within the com.android.systemui.statusbar.notification package. */ @Module(includes = { - FooterViewModelModule.class, KeyguardNotificationVisibilityProviderModule.class, NotificationDataLayerModule.class, NotificationDomainLayerModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt index 0c040c855368..502fb51ba5c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/ActiveNotificationsInteractor.kt @@ -76,11 +76,14 @@ constructor( val allNotificationsCountValue: Int get() = repository.activeNotifications.value.individuals.size - /** The notifications that are promoted and ongoing. Sorted by priority order. */ + /** + * The notifications that are promoted and ongoing. + * + * This *may* include ongoing call notifications if the call notification also meets promotion + * criteria. + */ val promotedOngoingNotifications: Flow<List<ActiveNotificationModel>> = if (StatusBarNotifChips.isEnabled) { - // TODO(b/364653005): [ongoingCallNotification] should be incorporated into this flow - // instead of being separate. topLevelRepresentativeNotifications .map { notifs -> notifs.filter { it.promotedContent != null } } .distinctUntilChanged() @@ -98,10 +101,10 @@ constructor( val ongoingCallNotification: Flow<ActiveNotificationModel?> = allRepresentativeNotifications .map { notifMap -> - // Once a call has started, its `whenTime` should stay the same, so we can use it as - // a stable sort value. notifMap.values - .filter { it.callType == CallType.Ongoing } + .filter { it.isOngoingCallNotification() } + // Once a call has started, its `whenTime` should stay the same, so we can use + // it as a stable sort value. .minByOrNull { it.whenTime } } .distinctUntilChanged() @@ -153,4 +156,8 @@ constructor( fun setNotifStats(notifStats: NotifStats) { repository.notifStats.value = notifStats } + + companion object { + fun ActiveNotificationModel.isOngoingCallNotification() = this.callType == CallType.Ongoing + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt index 17b6e9f572c9..e5cc3b973c51 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationIconInteractor.kt @@ -16,16 +16,19 @@ package com.android.systemui.statusbar.notification.domain.interactor import android.graphics.Rect +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.data.repository.HeadsUpNotificationIconViewStateRepository import javax.inject.Inject import kotlinx.coroutines.flow.Flow -/** Domain logic pertaining to heads up notification icons. */ +/** + * Domain logic pertaining to heads up notification icons. + * + * If [StatusBarNoHunBehavior] is enabled, this class should do nothing. + */ class HeadsUpNotificationIconInteractor @Inject -constructor( - private val repository: HeadsUpNotificationIconViewStateRepository, -) { +constructor(private val repository: HeadsUpNotificationIconViewStateRepository) { /** Notification key for a notification icon to show isolated, or `null` if none. */ val isolatedIconLocation: Flow<Rect?> = repository.isolatedIconLocation @@ -34,11 +37,13 @@ constructor( /** Updates the location where isolated notification icons are shown. */ fun setIsolatedIconLocation(rect: Rect?) { + StatusBarNoHunBehavior.assertInLegacyMode() repository.isolatedIconLocation.value = rect } /** Updates which notification will have its icon displayed isolated. */ fun setIsolatedIconNotificationKey(key: String?) { + StatusBarNoHunBehavior.assertInLegacyMode() repository.isolatedNotification.value = key } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java index a670f69df601..d401283aa84e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java @@ -40,6 +40,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import com.android.systemui.res.R; +import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.footer.shared.NotifRedesignFooter; import com.android.systemui.statusbar.notification.row.FooterViewButton; @@ -153,10 +154,12 @@ public class FooterView extends StackScrollerDecorView { DumpUtilsKt.withIncreasedIndent(pw, () -> { // TODO: b/375010573 - update dumps for redesign pw.println("visibility: " + DumpUtilsKt.visibilityString(getVisibility())); - pw.println("manageButton visibility: " - + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility())); - pw.println("dismissButton visibility: " - + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility())); + if (mManageOrHistoryButton != null) + pw.println("mManageOrHistoryButton visibility: " + + DumpUtilsKt.visibilityString(mManageOrHistoryButton.getVisibility())); + if (mClearAllButton != null) + pw.println("mClearAllButton visibility: " + + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility())); }); } @@ -333,11 +336,9 @@ public class FooterView extends StackScrollerDecorView { /** * Whether the touch is outside the Clear all button. - * - * TODO(b/293167744): This is an artifact from the time when we could press underneath the - * shade to dismiss it. Check if it's safe to remove. */ public boolean isOnEmptySpace(float touchX, float touchY) { + SceneContainerFlag.assertInLegacyMode(); return touchX < mContent.getX() || touchX > mContent.getX() + mContent.getWidth() || touchY < mContent.getY() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt index 5696e9f0c5a2..c895c41960d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification.footer.ui.viewmodel import android.content.Intent import android.provider.Settings import com.android.internal.jank.InteractionJankMonitor -import com.android.systemui.dagger.SysUISingleton import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.shared.notifications.domain.interactor.NotificationSettingsInteractor @@ -32,10 +31,8 @@ import com.android.systemui.util.kotlin.sample import com.android.systemui.util.ui.AnimatableEvent import com.android.systemui.util.ui.AnimatedValue import com.android.systemui.util.ui.toAnimatedValueFlow -import dagger.Module -import dagger.Provides -import java.util.Optional -import javax.inject.Provider +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged @@ -44,7 +41,9 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart /** ViewModel for [FooterView]. */ -class FooterViewModel( +class FooterViewModel +@AssistedInject +constructor( activeNotificationsInteractor: ActiveNotificationsInteractor, notificationSettingsInteractor: NotificationSettingsInteractor, seenNotificationsInteractor: SeenNotificationsInteractor, @@ -141,25 +140,9 @@ class FooterViewModel( AnimatedValue.NotAnimating(!messageVisible) }, ) -} -// TODO: b/293167744 - remove this, use new viewmodel style -@Module -object FooterViewModelModule { - @Provides - @SysUISingleton - fun provideOptional( - activeNotificationsInteractor: Provider<ActiveNotificationsInteractor>, - notificationSettingsInteractor: Provider<NotificationSettingsInteractor>, - seenNotificationsInteractor: Provider<SeenNotificationsInteractor>, - shadeInteractor: Provider<ShadeInteractor>, - ): Optional<FooterViewModel> = - Optional.of( - FooterViewModel( - activeNotificationsInteractor.get(), - notificationSettingsInteractor.get(), - seenNotificationsInteractor.get(), - shadeInteractor.get(), - ) - ) + @AssistedFactory + interface Factory { + fun create(): FooterViewModel + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java index d02e17cab534..0171fb72e158 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java @@ -1425,7 +1425,12 @@ public class HeadsUpManagerImpl } } - return (mEntry.isRowPinned() && mExpanded) + // Promoted notifications are always shown as expanded, and we don't want them to ever + // be sticky. + boolean isStickyDueToExpansion = + mEntry.isRowPinned() && mExpanded && !mEntry.isPromotedOngoing(); + + return isStickyDueToExpansion || mRemoteInputActive || hasFullScreenIntent(mEntry); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt index 643ee249e75e..348552f81fa7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt @@ -32,6 +32,7 @@ import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.collection.NotifCollection import com.android.systemui.statusbar.notification.icon.IconPack import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore @@ -81,7 +82,9 @@ object NotificationIconContainerViewBinder { StatusBarIconViewBinder.bindIconColors(sbiv, iconColors, contrastColorUtil) } } - launch { viewModel.bindIsolatedIcon(view, viewStore) } + if (!StatusBarNoHunBehavior.isEnabled) { + launch { viewModel.bindIsolatedIcon(view, viewStore) } + } launch { viewModel.animationsEnabled.bindAnimationsEnabled(view) } } @@ -146,6 +149,7 @@ object NotificationIconContainerViewBinder { view: NotificationIconContainer, viewStore: IconViewStore, ) { + StatusBarNoHunBehavior.assertInLegacyMode() coroutineScope { launch { isolatedIconLocation.collectTracingEach("NIC#isolatedIconLocation") { location -> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt index e1032820fb71..8f43c323aeb9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt @@ -23,6 +23,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor import com.android.systemui.statusbar.notification.icon.domain.interactor.StatusBarNotificationIconsInteractor import com.android.systemui.statusbar.phone.domain.interactor.DarkIconInteractor @@ -37,7 +38,9 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -92,31 +95,42 @@ constructor( /** An Icon to show "isolated" in the IconContainer. */ val isolatedIcon: Flow<AnimatedValue<NotificationIconInfo?>> = - headsUpIconInteractor.isolatedNotification - .combine(icons) { isolatedNotif, iconsViewData -> - isolatedNotif?.let { - iconsViewData.visibleIcons.firstOrNull { it.notifKey == isolatedNotif } - } - } - .distinctUntilChanged() - .flowOn(bgContext) - .conflate() - .distinctUntilChanged() - .pairwise(initialValue = null) - .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion -> - val animate = - when { - iconInfo?.notifKey == prev?.notifKey -> false - iconInfo == null || prev == null -> shadeExpansion == 0f - else -> false + if (StatusBarNoHunBehavior.isEnabled) { + flowOf(AnimatedValue.NotAnimating(null)) + } else { + headsUpIconInteractor.isolatedNotification + .combine(icons) { isolatedNotif, iconsViewData -> + isolatedNotif?.let { + iconsViewData.visibleIcons.firstOrNull { it.notifKey == isolatedNotif } } - AnimatableEvent(iconInfo, animate) - } - .toAnimatedValueFlow() + } + .distinctUntilChanged() + .flowOn(bgContext) + .conflate() + .distinctUntilChanged() + .pairwise(initialValue = null) + .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion -> + val animate = + when { + iconInfo?.notifKey == prev?.notifKey -> false + iconInfo == null || prev == null -> shadeExpansion == 0f + else -> false + } + AnimatableEvent(iconInfo, animate) + } + .toAnimatedValueFlow() + } /** Location to show an isolated icon, if there is one. */ val isolatedIconLocation: Flow<Rect> = - headsUpIconInteractor.isolatedIconLocation.filterNotNull().conflate().distinctUntilChanged() + if (StatusBarNoHunBehavior.isEnabled) { + emptyFlow() + } else { + headsUpIconInteractor.isolatedIconLocation + .filterNotNull() + .conflate() + .distinctUntilChanged() + } private class IconColorsImpl(override val tint: Int, private val areas: Collection<Rect>) : NotificationIconColors { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt index 0a9899e88d24..c3266fc57c2e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt @@ -93,7 +93,6 @@ constructor( clickerBuilder.build(bubblesOptional, notificationActivityStarter) ) notificationRowBinder.setUpWithPresenter(presenter, listContainer) - headsUpViewBinder.setPresenter(presenter) notifBindPipelineInitializer.initialize() animatedImageNotificationManager.bind() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java index 32ec02319241..9988f729a11a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinder.java @@ -23,9 +23,7 @@ import android.util.ArrayMap; import androidx.annotation.Nullable; import androidx.core.os.CancellationSignal; -import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.dagger.SysUISingleton; -import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator; import com.android.systemui.statusbar.notification.row.RowContentBindParams; @@ -45,30 +43,18 @@ import javax.inject.Inject; @SysUISingleton public class HeadsUpViewBinder { private final RowContentBindStage mStage; - private final NotificationMessagingUtil mNotificationMessagingUtil; private final Map<NotificationEntry, CancellationSignal> mOngoingBindCallbacks = new ArrayMap<>(); private final HeadsUpViewBinderLogger mLogger; - private NotificationPresenter mNotificationPresenter; @Inject - HeadsUpViewBinder( - NotificationMessagingUtil notificationMessagingUtil, - RowContentBindStage bindStage, HeadsUpViewBinderLogger logger) { - mNotificationMessagingUtil = notificationMessagingUtil; + HeadsUpViewBinder(RowContentBindStage bindStage, HeadsUpViewBinderLogger logger) { mStage = bindStage; mLogger = logger; } /** - * Set notification presenter to determine parameters for heads up view inflation. - */ - public void setPresenter(NotificationPresenter presenter) { - mNotificationPresenter = presenter; - } - - /** * Bind heads up view to the notification row. * @param callback callback after heads up view is bound */ @@ -77,15 +63,9 @@ public class HeadsUpViewBinder { boolean isPinnedByUser, @Nullable HeadsUpBindCallback callback) { RowContentBindParams params = mStage.getStageParams(entry); - final boolean isImportantMessage = mNotificationMessagingUtil.isImportantMessaging( - entry.getSbn(), entry.getImportance()); - final boolean useIncreasedHeadsUp = isImportantMessage - && !mNotificationPresenter.isPresenterFullyCollapsed(); - params.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp); params.requireContentViews(FLAG_CONTENT_VIEW_HEADS_UP); CancellationSignal signal = mStage.requestRebind(entry, en -> { mLogger.entryBoundSuccessfully(entry); - en.getRow().setUsesIncreasedHeadsUpHeight(params.useIncreasedHeadsUpHeight()); // requestRebind promises that if we called cancel before this callback would be // invoked, then we will not enter this callback, and because we always cancel before // adding to this map, we know this will remove the correct signal. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt index 258d80c60cd7..a175f90c384a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt @@ -147,6 +147,7 @@ data class PromotedNotificationContentModel( * Returns true if the given notification should be considered promoted when deciding * whether or not to show the status bar chip UI. */ + @JvmStatic fun isPromotedForStatusBarChip(notification: Notification): Boolean { // Notification.isPromotedOngoing checks the ui_rich_ongoing flag, but we want the // status bar chip to be ready before all the features behind the ui_rich_ongoing flag diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 95604c113a15..598ff09ba3b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -191,12 +191,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private int mMaxHeadsUpHeightBeforeP; private int mMaxHeadsUpHeightBeforeS; private int mMaxHeadsUpHeight; - private int mMaxHeadsUpHeightIncreased; private int mMaxSmallHeightBeforeN; private int mMaxSmallHeightBeforeP; private int mMaxSmallHeightBeforeS; private int mMaxSmallHeight; - private int mMaxSmallHeightLarge; private int mMaxExpandedHeight; private int mNotificationLaunchHeight; private boolean mMustStayOnScreen; @@ -414,8 +412,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private OnUserInteractionCallback mOnUserInteractionCallback; private NotificationGutsManager mNotificationGutsManager; private boolean mIsMinimized; - private boolean mUseIncreasedCollapsedHeight; - private boolean mUseIncreasedHeadsUpHeight; private float mTranslationWhenRemoved; private boolean mWasChildInGroupWhenRemoved; private final NotificationInlineImageResolver mImageResolver; @@ -828,8 +824,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } else if (isCallLayout) { smallHeight = mMaxExpandedHeight; - } else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) { - smallHeight = mMaxSmallHeightLarge; } else { smallHeight = mMaxSmallHeight; } @@ -845,8 +839,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } else { headsUpHeight = mMaxHeadsUpHeightBeforeS; } - } else if (mUseIncreasedHeadsUpHeight && layout == mPrivateLayout) { - headsUpHeight = mMaxHeadsUpHeightIncreased; } else { headsUpHeight = mMaxHeadsUpHeight; } @@ -1848,14 +1840,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mIsMinimized; } - public void setUsesIncreasedCollapsedHeight(boolean use) { - mUseIncreasedCollapsedHeight = use; - } - - public void setUsesIncreasedHeadsUpHeight(boolean use) { - mUseIncreasedHeadsUpHeight = use; - } - /** * Interface for logging {{@link ExpandableNotificationRow} events.} */ @@ -2086,8 +2070,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mMaxSmallHeight = NotificationUtils.getFontScaledHeight(mContext, R.dimen.notification_min_height); } - mMaxSmallHeightLarge = NotificationUtils.getFontScaledHeight(mContext, - R.dimen.notification_min_height_increased); mMaxExpandedHeight = NotificationUtils.getFontScaledHeight(mContext, R.dimen.notification_max_height); mMaxHeadsUpHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext, @@ -2098,8 +2080,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView R.dimen.notification_max_heads_up_height_before_s); mMaxHeadsUpHeight = NotificationUtils.getFontScaledHeight(mContext, R.dimen.notification_max_heads_up_height); - mMaxHeadsUpHeightIncreased = NotificationUtils.getFontScaledHeight(mContext, - R.dimen.notification_max_heads_up_height_increased); Resources res = getResources(); mEnableNonGroupedNotificationExpand = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt index e27ff7d6746b..793b3b8b1e42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt @@ -17,39 +17,210 @@ package com.android.systemui.statusbar.notification.row import android.content.Context +import android.graphics.BlendMode import android.graphics.Canvas +import android.graphics.Color import android.graphics.ColorFilter +import android.graphics.LinearGradient import android.graphics.Paint +import android.graphics.Path import android.graphics.PixelFormat +import android.graphics.Rect +import android.graphics.RuntimeShader +import android.graphics.Shader import android.graphics.drawable.Drawable +import android.widget.FrameLayout +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import com.android.internal.graphics.ColorUtils +import com.android.systemui.res.R +import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary +import kotlin.math.max +import kotlin.math.roundToInt /** - * A background style for smarter-smart-actions. - * - * TODO(b/383567383) implement final UX + * A background style for smarter-smart-actions. The style is composed by a simplex3d noise, + * overlaid with sparkles. */ -class MagicActionBackgroundDrawable(context: Context) : Drawable() { +class MagicActionBackgroundDrawable( + context: Context, + primaryContainer: Int? = null, + private val seed: Float = 0f, +) : Drawable() { + + private val pixelDensity = context.resources.displayMetrics.density + private val cornerRadius = + context.resources.getDimensionPixelSize(R.dimen.smart_reply_button_corner_radius).toFloat() + private val outlineStrokeWidth = + context.resources + .getDimensionPixelSize(R.dimen.smart_action_button_outline_stroke_width) + .toFloat() + private val buttonShape = Path() + private val paddingVertical = + context.resources + .getDimensionPixelSize(R.dimen.smart_reply_button_padding_vertical) + .toFloat() + + /** The color of the button background. */ + private val mainColor = + primaryContainer + ?: context.getColor(com.android.internal.R.color.materialColorPrimaryContainer) - private var _alpha: Int = 255 - private var _colorFilter: ColorFilter? = null - private val paint = - Paint().apply { - color = context.getColor(com.android.internal.R.color.materialColorPrimaryContainer) + /** Slightly dimmed down version of [mainColor] used on the simplex noise. */ + private val dimColor: Int + get() { + val labColor = arrayOf(0.0, 0.0, 0.0).toDoubleArray() + ColorUtils.colorToLAB(mainColor, labColor) + val camColor = ColorUtils.colorToCAM(mainColor) + return ColorUtils.CAMToColor( + camColor.hue, + camColor.chroma, + max(0f, (labColor[0] - 20).toFloat()), + ) } + private val bgShader = MagicActionBackgroundShader() + private val bgPaint = Paint() + private val outlinePaint = Paint() + + init { + bgShader.setColorUniform("in_color", mainColor) + bgShader.setColorUniform("in_dimColor", dimColor) + bgPaint.shader = bgShader + outlinePaint.style = Paint.Style.STROKE + // Stroke is doubled in width and then clipped, to avoid anti-aliasing artifacts at the edge + // of the rectangle. + outlinePaint.strokeWidth = outlineStrokeWidth * 2 + outlinePaint.blendMode = BlendMode.SCREEN + outlinePaint.alpha = (255 * 0.32f).roundToInt() + } + override fun draw(canvas: Canvas) { - canvas.drawRect(bounds, paint) + // We clip instead of drawing 2 rounded rects, otherwise there will be artifacts where + // around the button background and the outline. + canvas.clipPath(buttonShape) + + canvas.drawRect(bounds, bgPaint) + canvas.drawRoundRect( + bounds.left.toFloat(), + bounds.top + paddingVertical, + bounds.right.toFloat(), + bounds.bottom - paddingVertical, + cornerRadius, + cornerRadius, + outlinePaint, + ) + } + + override fun onBoundsChange(bounds: Rect) { + super.onBoundsChange(bounds) + + val width = bounds.width().toFloat() + val height = bounds.height() - paddingVertical * 2 + if (width == 0f || height == 0f) return + + bgShader.setFloatUniform("in_gridNum", NOISE_SIZE) + bgShader.setFloatUniform("in_spkarkleAlpha", SPARKLE_ALPHA) + bgShader.setFloatUniform("in_noiseMove", 0f, 0f, 0f) + bgShader.setFloatUniform("in_size", width, height) + bgShader.setFloatUniform("in_aspectRatio", width / height) + bgShader.setFloatUniform("in_time", seed) + bgShader.setFloatUniform("in_pixelDensity", pixelDensity) + + buttonShape.reset() + buttonShape.addRoundRect( + bounds.left.toFloat(), + bounds.top + paddingVertical, + bounds.right.toFloat(), + bounds.bottom - paddingVertical, + cornerRadius, + cornerRadius, + Path.Direction.CW, + ) + + val outlineGradient = + LinearGradient( + bounds.left.toFloat(), + 0f, + bounds.right.toFloat(), + 0f, + mainColor, + ColorUtils.setAlphaComponent(mainColor, 0), + Shader.TileMode.CLAMP, + ) + outlinePaint.shader = outlineGradient } override fun setAlpha(alpha: Int) { - _alpha = alpha + bgPaint.alpha = alpha invalidateSelf() } override fun setColorFilter(colorFilter: ColorFilter?) { - _colorFilter = colorFilter + bgPaint.colorFilter = colorFilter invalidateSelf() } override fun getOpacity(): Int = PixelFormat.TRANSLUCENT + + companion object { + /** Smoothness of the turbulence. Larger numbers yield more detail. */ + private const val NOISE_SIZE = 0.7f + + /** Strength of the sparkles overlaid on the turbulence. */ + private const val SPARKLE_ALPHA = 0.15f + } +} + +private class MagicActionBackgroundShader : RuntimeShader(SHADER) { + + // language=AGSL + companion object { + private const val UNIFORMS = + """ + uniform float in_gridNum; + uniform vec3 in_noiseMove; + uniform vec2 in_size; + uniform float in_aspectRatio; + uniform half in_time; + uniform half in_pixelDensity; + uniform float in_spkarkleAlpha; + layout(color) uniform vec4 in_color; + layout(color) uniform vec4 in_dimColor; + """ + private const val MAIN_SHADER = + """vec4 main(vec2 p) { + vec2 uv = p / in_size.xy; + uv.x *= in_aspectRatio; + vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum; + half luma = 1.0 - getLuminosity(half3(simplex3d(noiseP))); + half4 turbulenceColor = mix(in_color, in_dimColor, luma); + float sparkle = sparkles(p - mod(p, in_pixelDensity * 0.8), in_time); + sparkle = min(sparkle * in_spkarkleAlpha, in_spkarkleAlpha); + return turbulenceColor + half4(half3(sparkle), 1.0); + } + """ + private const val SHADER = UNIFORMS + ShaderUtilLibrary.SHADER_LIB + MAIN_SHADER + } +} + +// @Preview +@Composable +fun DrawablePreview() { + AndroidView( + factory = { context -> + FrameLayout(context).apply { + background = + MagicActionBackgroundDrawable( + context = context, + primaryContainer = Color.parseColor("#c5eae2"), + seed = 0f, + ) + } + }, + modifier = Modifier.size(100.dp, 50.dp), + ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index 70e27a981b49..57fe24f40acb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -436,8 +436,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { logger.logAsyncTaskProgress(entryForLogging, "creating contracted remote view"); - result.newContentView = createContentView(builder, bindParams.isMinimized, - bindParams.usesIncreasedHeight); + result.newContentView = createContentView(builder, bindParams.isMinimized); } if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) { @@ -451,8 +450,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder if (isHeadsUpCompact) { result.newHeadsUpView = builder.createCompactHeadsUpContentView(); } else { - result.newHeadsUpView = builder.createHeadsUpContentView( - bindParams.usesIncreasedHeadsUpHeight); + result.newHeadsUpView = builder.createHeadsUpContentView(); } } @@ -462,7 +460,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder && bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT) { result.newPublicView = createSensitiveContentMessageNotification( row.getEntry().getSbn().getNotification(), builder.getStyle(), - systemUiContext, packageContext).createContentView(true); + systemUiContext, packageContext).createContentView(); } else { result.newPublicView = builder.makePublicContentView(bindParams.isMinimized); } @@ -504,6 +502,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder CharSequence redactedMessage = systemUiContext.getString( R.string.redacted_notification_single_line_text ); + redacted.setWhen(original.getWhen()); if (originalStyle instanceof MessagingStyle oldStyle) { MessagingStyle newStyle = new MessagingStyle(oldStyle.getUser()); @@ -1134,11 +1133,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder } private static RemoteViews createContentView(Notification.Builder builder, - boolean isMinimized, boolean useLarge) { + boolean isMinimized) { if (isMinimized) { return builder.makeLowPriorityContentView(false /* useRegularSubtext */); } - return builder.createContentView(useLarge); + return builder.createContentView(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java index 1cef8791e0ea..0be1d5d9d79d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java @@ -143,11 +143,8 @@ public interface NotificationRowContentBinder { */ class BindParams { - public BindParams(boolean minimized, boolean increasedHeight, - boolean increasedHeadsUpHeight, int redaction) { + public BindParams(boolean minimized, int redaction) { isMinimized = minimized; - usesIncreasedHeight = increasedHeight; - usesIncreasedHeadsUpHeight = increasedHeadsUpHeight; redactionType = redaction; } @@ -157,16 +154,6 @@ public interface NotificationRowContentBinder { public final boolean isMinimized; /** - * Use increased height when binding contracted view. - */ - public final boolean usesIncreasedHeight; - - /** - * Use increased height when binding heads up views. - */ - public final boolean usesIncreasedHeadsUpHeight; - - /** * Controls the type of public view to show, if a public view is requested */ public final @RedactionType int redactionType; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt index c619b17f1ad8..49e38def98a6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt @@ -822,11 +822,7 @@ constructor( entryForLogging, "creating contracted remote view", ) - createContentView( - builder, - bindParams.isMinimized, - bindParams.usesIncreasedHeight, - ) + createContentView(builder, bindParams.isMinimized) } else null val expanded = if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) { @@ -846,7 +842,7 @@ constructor( if (isHeadsUpCompact) { builder.createCompactHeadsUpContentView() } else { - builder.createHeadsUpContentView(bindParams.usesIncreasedHeadsUpHeight) + @Suppress("DEPRECATION") builder.createHeadsUpContentView() } } else null val public = @@ -862,7 +858,7 @@ constructor( systemUiContext, packageContext, ) - .createContentView(bindParams.usesIncreasedHeight) + .createContentView() } else { builder.makePublicContentView(bindParams.isMinimized) } @@ -1654,11 +1650,12 @@ constructor( private fun createContentView( builder: Notification.Builder, isMinimized: Boolean, - useLarge: Boolean, ): RemoteViews { return if (isMinimized) { builder.makeLowPriorityContentView(false /* useRegularSubtext */) - } else builder.createContentView(useLarge) + } else { + @Suppress("DEPRECATION") builder.createContentView() + } } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java index bc44cb0e1074..adbff10a629b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java @@ -20,7 +20,6 @@ import static com.android.systemui.statusbar.NotificationLockscreenUserManager.R import static com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED; -import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; @@ -29,8 +28,6 @@ import com.android.systemui.statusbar.notification.row.NotificationRowContentBin */ public final class RowContentBindParams { private boolean mUseMinimized; - private boolean mUseIncreasedHeight; - private boolean mUseIncreasedHeadsUpHeight; private boolean mViewsNeedReinflation; private @InflationFlag int mContentViews = DEFAULT_INFLATION_FLAGS; private @RedactionType int mRedactionType = REDACTION_TYPE_NONE; @@ -75,34 +72,6 @@ public final class RowContentBindParams { } /** - * Set whether content should use an increased height version of its contracted view. - */ - public void setUseIncreasedCollapsedHeight(boolean useIncreasedHeight) { - if (mUseIncreasedHeight != useIncreasedHeight) { - mDirtyContentViews |= FLAG_CONTENT_VIEW_CONTRACTED; - } - mUseIncreasedHeight = useIncreasedHeight; - } - - public boolean useIncreasedHeight() { - return mUseIncreasedHeight; - } - - /** - * Set whether content should use an increased height version of its heads up view. - */ - public void setUseIncreasedHeadsUpHeight(boolean useIncreasedHeadsUpHeight) { - if (mUseIncreasedHeadsUpHeight != useIncreasedHeadsUpHeight) { - mDirtyContentViews |= FLAG_CONTENT_VIEW_HEADS_UP; - } - mUseIncreasedHeadsUpHeight = useIncreasedHeadsUpHeight; - } - - public boolean useIncreasedHeadsUpHeight() { - return mUseIncreasedHeadsUpHeight; - } - - /** * Require the specified content views to be bound after the rebind request. * * @see InflationFlag @@ -169,10 +138,8 @@ public final class RowContentBindParams { @Override public String toString() { return String.format("RowContentBindParams[mContentViews=%x mDirtyContentViews=%x " - + "mUseMinimized=%b mUseIncreasedHeight=%b " - + "mUseIncreasedHeadsUpHeight=%b mViewsNeedReinflation=%b]", - mContentViews, mDirtyContentViews, mUseMinimized, mUseIncreasedHeight, - mUseIncreasedHeadsUpHeight, mViewsNeedReinflation); + + "mUseMinimized=%b mViewsNeedReinflation=%b]", + mContentViews, mDirtyContentViews, mUseMinimized, mViewsNeedReinflation); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java index 53f74161e7fc..6883ec575d7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java @@ -72,8 +72,7 @@ public class RowContentBindStage extends BindStage<RowContentBindParams> { // Bind/unbind with parameters mBinder.unbindContent(entry, row, contentToUnbind); - BindParams bindParams = new BindParams(params.useMinimized(), params.useIncreasedHeight(), - params.useIncreasedHeadsUpHeight(), params.getRedactionType()); + BindParams bindParams = new BindParams(params.useMinimized(), params.getRedactionType()); boolean forceInflate = params.needsReinflation(); InflationCallback inflationCallback = new InflationCallback() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/AppIconProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/AppIconProvider.kt index f3ee34f45a50..52a0f6f92355 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/AppIconProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/AppIconProvider.kt @@ -84,7 +84,16 @@ constructor(@ShadeDisplayAware private val sysuiContext: Context, dumpManager: D init { if (notificationsRedesignThemedAppIcons()) { // Initialize the controller so that we can support themed icons. - mThemeController = MonoIconThemeController() + mThemeController = + MonoIconThemeController( + colorProvider = { ctx -> + val res = ctx.resources + intArrayOf( + /* background */ res.getColor(R.color.materialColorPrimary), + /* icon */ res.getColor(R.color.materialColorSurfaceContainerHigh), + ) + } + ) } } } 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 a8a1318664f2..495b50869458 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 @@ -98,6 +98,7 @@ import com.android.systemui.shade.QSHeaderBoundsProvider; import com.android.systemui.shade.TouchLogger; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior; import com.android.systemui.statusbar.notification.ColorUpdateLogger; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.LaunchAnimationParameters; @@ -5339,7 +5340,7 @@ public class NotificationStackScrollLayout void onStatePostChange(boolean fromShadeLocked) { boolean onKeyguard = onKeyguard(); - if (mHeadsUpAppearanceController != null) { + if (mHeadsUpAppearanceController != null && !StatusBarNoHunBehavior.isEnabled()) { mHeadsUpAppearanceController.onStateChanged(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt index 1d7e658932ac..6385d53dbc8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationListViewBinder.kt @@ -99,6 +99,9 @@ constructor( .inflate(R.layout.status_bar_notification_shelf, view, false) as NotificationShelf view.setShelf(shelf) + // Create viewModels once, and only when needed. + val footerViewModel by lazy { viewModel.footerViewModelFactory.create() } + val emptyShadeViewModel by lazy { viewModel.emptyShadeViewModelFactory.create() } view.repeatWhenAttached { lifecycleScope.launch { if (SceneContainerFlag.isEnabled) { @@ -109,12 +112,18 @@ constructor( val hasNonClearableSilentNotifications: StateFlow<Boolean> = viewModel.hasNonClearableSilentNotifications.stateIn(this) - launch { reinflateAndBindFooter(view, hasNonClearableSilentNotifications) } + launch { + reinflateAndBindFooter( + footerViewModel, + view, + hasNonClearableSilentNotifications, + ) + } launch { if (ModesEmptyShadeFix.isEnabled) { - reinflateAndBindEmptyShade(view) + reinflateAndBindEmptyShade(emptyShadeViewModel, view) } else { - bindEmptyShadeLegacy(viewModel.emptyShadeViewFactory.create(), view) + bindEmptyShadeLegacy(emptyShadeViewModel, view) } } launch { bindSilentHeaderClickListener(view, hasNonClearableSilentNotifications) } @@ -134,31 +143,30 @@ constructor( } private suspend fun reinflateAndBindFooter( + footerViewModel: FooterViewModel, parentView: NotificationStackScrollLayout, hasNonClearableSilentNotifications: StateFlow<Boolean>, ) { - viewModel.footer.getOrNull()?.let { footerViewModel -> - // The footer needs to be re-inflated every time the theme or the font size changes. - configuration - .inflateLayout<FooterView>( - if (NotifRedesignFooter.isEnabled) R.layout.notification_2025_footer - else R.layout.status_bar_notification_footer, - parentView, - attachToRoot = false, - ) - .flowOn(backgroundDispatcher) - .collectLatest { footerView: FooterView -> - traceAsync("bind FooterView") { - parentView.setFooterView(footerView) - bindFooter( - footerView, - footerViewModel, - parentView, - hasNonClearableSilentNotifications, - ) - } + // The footer needs to be re-inflated every time the theme or the font size changes. + configuration + .inflateLayout<FooterView>( + if (NotifRedesignFooter.isEnabled) R.layout.notification_2025_footer + else R.layout.status_bar_notification_footer, + parentView, + attachToRoot = false, + ) + .flowOn(backgroundDispatcher) + .collectLatest { footerView: FooterView -> + traceAsync("bind FooterView") { + parentView.setFooterView(footerView) + bindFooter( + footerView, + footerViewModel, + parentView, + hasNonClearableSilentNotifications, + ) } - } + } } /** @@ -219,7 +227,10 @@ constructor( notificationActivityStarter.get().startHistoryIntent(view, /* showHistory= */ true) } - private suspend fun reinflateAndBindEmptyShade(parentView: NotificationStackScrollLayout) { + private suspend fun reinflateAndBindEmptyShade( + emptyShadeViewModel: EmptyShadeViewModel, + parentView: NotificationStackScrollLayout, + ) { ModesEmptyShadeFix.assertInNewMode() // The empty shade needs to be re-inflated every time the theme or the font size // changes. @@ -233,7 +244,7 @@ constructor( .collectLatest { emptyShadeView: EmptyShadeView -> traceAsync("bind EmptyShadeView") { parentView.setEmptyShadeView(emptyShadeView) - bindEmptyShade(emptyShadeView, viewModel.emptyShadeViewFactory.create()) + bindEmptyShade(emptyShadeView, emptyShadeViewModel) } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt index fcc671a5bae6..5ed1889de01e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt @@ -56,8 +56,8 @@ class NotificationListViewModel constructor( val shelf: NotificationShelfViewModel, val hideListViewModel: HideListViewModel, - val footer: Optional<FooterViewModel>, - val emptyShadeViewFactory: EmptyShadeViewModel.Factory, + val footerViewModelFactory: FooterViewModel.Factory, + val emptyShadeViewModelFactory: EmptyShadeViewModel.Factory, val logger: Optional<NotificationLoggerViewModel>, activeNotificationsInteractor: ActiveNotificationsInteractor, notificationStackInteractor: NotificationStackInteractor, 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 5d550226a79e..8e12e081e861 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 @@ -16,15 +16,21 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel +import androidx.compose.runtime.getValue import com.android.app.tracing.coroutines.launchTraced as launch +import com.android.compose.animation.scene.ContentKey import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.dump.DumpManager import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.lifecycle.ExclusiveActivatable +import com.android.systemui.lifecycle.Hydrator import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlag +import com.android.systemui.scene.shared.model.Overlays +import com.android.systemui.scene.shared.model.Scenes import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor @@ -63,6 +69,24 @@ constructor( tag = "NotificationsPlaceholderViewModel", ) { + private val hydrator = Hydrator("NotificationsPlaceholderViewModel") + + /** The content key to use for the notification shade. */ + val notificationsShadeContentKey: ContentKey by + hydrator.hydratedStateOf( + traceName = "notificationsShadeContentKey", + initialValue = getNotificationsShadeContentKey(shadeInteractor.shadeMode.value), + source = shadeInteractor.shadeMode.map { getNotificationsShadeContentKey(it) }, + ) + + /** The content key to use for the quick settings shade. */ + val quickSettingsShadeContentKey: ContentKey by + hydrator.hydratedStateOf( + traceName = "quickSettingsShadeContentKey", + initialValue = getQuickSettingsShadeContentKey(shadeInteractor.shadeMode.value), + source = shadeInteractor.shadeMode.map { getQuickSettingsShadeContentKey(it) }, + ) + /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */ val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES) @@ -71,6 +95,8 @@ constructor( override suspend fun onActivated(): Nothing { coroutineScope { + launch { hydrator.activate() } + launch { shadeInteractor.isAnyExpanded .filter { it } @@ -79,8 +105,7 @@ constructor( launch { sceneInteractor.transitionState - .map { state -> state is ObservableTransitionState.Idle } - .filter { it } + .filter { it is ObservableTransitionState.Idle } .collect { headsUpNotificationInteractor.onTransitionIdle() } } } @@ -163,6 +188,18 @@ constructor( interactor.setAccessibilityScrollEventConsumer(consumer) } + private fun getNotificationsShadeContentKey(shadeMode: ShadeMode): ContentKey { + return if (shadeMode is ShadeMode.Dual) Overlays.NotificationsShade else Scenes.Shade + } + + private fun getQuickSettingsShadeContentKey(shadeMode: ShadeMode): ContentKey { + return when (shadeMode) { + is ShadeMode.Single -> Scenes.QuickSettings + is ShadeMode.Split -> Scenes.Shade + is ShadeMode.Dual -> Overlays.QuickSettingsShade + } + } + @AssistedFactory interface Factory { fun create(): NotificationsPlaceholderViewModel diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 53a29505510b..548ab8311144 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips; import com.android.systemui.statusbar.core.StatusBarRootModernization; +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.SourceType; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -151,19 +152,21 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar mOperatorNameViewOptional = operatorNameViewOptional; mDarkIconDispatcher = darkIconDispatcher; - mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - if (shouldHeadsUpStatusBarBeVisible()) { - updateTopEntry(); - - // trigger scroller to notify the latest panel translation - mStackScrollerController.requestLayout(); + if (!StatusBarNoHunBehavior.isEnabled()) { + mView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (shouldHeadsUpStatusBarBeVisible()) { + updatePinnedStatus(); + + // trigger scroller to notify the latest panel translation + mStackScrollerController.requestLayout(); + } + mView.removeOnLayoutChangeListener(this); } - mView.removeOnLayoutChangeListener(this); - } - }); + }); + } mBypassController = bypassController; mStatusBarStateController = stateController; mPhoneStatusBarTransitions = phoneStatusBarTransitions; @@ -175,13 +178,15 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @Override protected void onViewAttached() { mHeadsUpManager.addListener(this); - mView.setOnDrawingRectChangedListener(this::updateIsolatedIconLocation); - updateIsolatedIconLocation(); - mWakeUpCoordinator.addListener(this); + if (!StatusBarNoHunBehavior.isEnabled()) { + mView.setOnDrawingRectChangedListener(this::updateIsolatedIconLocation); + updateIsolatedIconLocation(); + mDarkIconDispatcher.addDarkReceiver(this); + mWakeUpCoordinator.addListener(this); + } getShadeHeadsUpTracker().addTrackingHeadsUpListener(mSetTrackingHeadsUp); getShadeHeadsUpTracker().setHeadsUpAppearanceController(this); mStackScrollerController.addOnExpandedHeightChangedListener(mSetExpandedHeight); - mDarkIconDispatcher.addDarkReceiver(this); } private ShadeHeadsUpTracker getShadeHeadsUpTracker() { @@ -191,22 +196,25 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @Override protected void onViewDetached() { mHeadsUpManager.removeListener(this); - mView.setOnDrawingRectChangedListener(null); - mHeadsUpNotificationIconInteractor.setIsolatedIconLocation(null); - mWakeUpCoordinator.removeListener(this); + if (!StatusBarNoHunBehavior.isEnabled()) { + mView.setOnDrawingRectChangedListener(null); + mHeadsUpNotificationIconInteractor.setIsolatedIconLocation(null); + mDarkIconDispatcher.removeDarkReceiver(this); + mWakeUpCoordinator.removeListener(this); + } getShadeHeadsUpTracker().removeTrackingHeadsUpListener(mSetTrackingHeadsUp); getShadeHeadsUpTracker().setHeadsUpAppearanceController(null); mStackScrollerController.removeOnExpandedHeightChangedListener(mSetExpandedHeight); - mDarkIconDispatcher.removeDarkReceiver(this); } private void updateIsolatedIconLocation() { + StatusBarNoHunBehavior.assertInLegacyMode(); mHeadsUpNotificationIconInteractor.setIsolatedIconLocation(mView.getIconDrawingRect()); } @Override public void onHeadsUpPinned(NotificationEntry entry) { - updateTopEntry(); + updatePinnedStatus(); updateHeader(entry); updateHeadsUpAndPulsingRoundness(entry); } @@ -217,7 +225,10 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar mPhoneStatusBarTransitions.onHeadsUpStateChanged(isHeadsUp); } - private void updateTopEntry() { + private void updatePinnedStatus() { + if (StatusBarNoHunBehavior.isEnabled()) { + return; + } NotificationEntry newEntry = null; if (shouldHeadsUpStatusBarBeVisible()) { newEntry = mHeadsUpManager.getTopEntry(); @@ -239,6 +250,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar } private static @Nullable String getIsolatedIconKey(NotificationEntry newEntry) { + StatusBarNoHunBehavior.assertInLegacyMode(); if (newEntry == null) { return null; } @@ -259,6 +271,9 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar } private void setPinnedStatus(PinnedStatus pinnedStatus) { + if (StatusBarNoHunBehavior.isEnabled()) { + return; + } if (mPinnedStatus != pinnedStatus) { mPinnedStatus = pinnedStatus; @@ -292,6 +307,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar } private void updateParentClipping(boolean shouldClip) { + StatusBarNoHunBehavior.assertInLegacyMode(); ViewClippingUtil.setClippingDeactivated( mView, !shouldClip, mParentClippingParams); } @@ -319,6 +335,8 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar * */ private void hide(View view, int endState, Runnable callback) { + StatusBarNoHunBehavior.assertInLegacyMode(); + if (mAnimationsEnabled) { CrossFadeHelper.fadeOut(view, CONTENT_FADE_DURATION /* duration */, 0 /* delay */, () -> { @@ -336,6 +354,8 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar } private void show(View view) { + StatusBarNoHunBehavior.assertInLegacyMode(); + if (mAnimationsEnabled) { CrossFadeHelper.fadeIn(view, CONTENT_FADE_DURATION /* duration */, CONTENT_FADE_DELAY /* delay */); @@ -351,6 +371,9 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @VisibleForTesting public PinnedStatus getPinnedStatus() { + if (StatusBarNoHunBehavior.isEnabled()) { + return PinnedStatus.NotPinned; + } return mPinnedStatus; } @@ -375,6 +398,10 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar */ @Deprecated public boolean shouldHeadsUpStatusBarBeVisible() { + if (StatusBarNoHunBehavior.isEnabled()) { + return false; + } + if (StatusBarNotifChips.isEnabled()) { return canShowHeadsUp() && mHeadsUpManager.pinnedHeadsUpStatus() == PinnedStatus.PinnedBySystem; @@ -388,7 +415,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @Override public void onHeadsUpUnPinned(NotificationEntry entry) { - updateTopEntry(); + updatePinnedStatus(); updateHeader(entry); updateHeadsUpAndPulsingRoundness(entry); } @@ -406,7 +433,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar updateHeadsUpHeaders(); } if (isExpanded() != oldIsExpanded) { - updateTopEntry(); + updatePinnedStatus(); } } @@ -476,15 +503,18 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @Override public void onDarkChanged(ArrayList<Rect> areas, float darkIntensity, int tint) { + StatusBarNoHunBehavior.assertInLegacyMode(); mView.onDarkChanged(areas, darkIntensity, tint); } public void onStateChanged() { - updateTopEntry(); + StatusBarNoHunBehavior.assertInLegacyMode(); + updatePinnedStatus(); } @Override public void onFullyHiddenChanged(boolean isFullyHidden) { - updateTopEntry(); + StatusBarNoHunBehavior.assertInLegacyMode(); + updatePinnedStatus(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index c396512ce3a5..1a97ab635028 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -41,6 +41,7 @@ import com.android.internal.statusbar.StatusBarIcon; import com.android.settingslib.Utils; import com.android.systemui.res.R; import com.android.systemui.statusbar.StatusBarIconView; +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior; import com.android.systemui.statusbar.notification.stack.AnimationFilter; import com.android.systemui.statusbar.notification.stack.AnimationProperties; import com.android.systemui.statusbar.notification.stack.ViewState; @@ -163,12 +164,12 @@ public class NotificationIconContainer extends ViewGroup { private IconState mFirstVisibleIconState; private float mVisualOverflowStart; private boolean mIsShowingOverflowDot; - private StatusBarIconView mIsolatedIcon; - private Rect mIsolatedIconLocation; + @Nullable private StatusBarIconView mIsolatedIcon; + @Nullable private Rect mIsolatedIconLocation; private final int[] mAbsolutePosition = new int[2]; - private View mIsolatedIconForAnimation; + @Nullable private View mIsolatedIconForAnimation; private int mThemedTextColorPrimary; - private Runnable mIsolatedIconAnimationEndRunnable; + @Nullable private Runnable mIsolatedIconAnimationEndRunnable; private boolean mUseIncreasedIconScale; public NotificationIconContainer(Context context, AttributeSet attrs) { @@ -379,6 +380,9 @@ public class NotificationIconContainer extends ViewGroup { if (areAnimationsEnabled(icon) && !isReplacingIcon) { addTransientView(icon, 0); boolean isIsolatedIcon = child == mIsolatedIcon; + if (StatusBarNoHunBehavior.isEnabled()) { + isIsolatedIcon = false; + } icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */, () -> removeTransientView(icon), isIsolatedIcon ? CONTENT_FADE_DURATION : 0); @@ -539,7 +543,7 @@ public class NotificationIconContainer extends ViewGroup { iconState.setXTranslation(getRtlIconTranslationX(iconState, view)); } } - if (mIsolatedIcon != null) { + if (!StatusBarNoHunBehavior.isEnabled() && mIsolatedIcon != null) { IconState iconState = mIconStates.get(mIsolatedIcon); if (iconState != null) { // Most of the time the icon isn't yet added when this is called but only happening @@ -685,17 +689,20 @@ public class NotificationIconContainer extends ViewGroup { public void showIconIsolatedAnimated(StatusBarIconView icon, @Nullable Runnable onAnimationEnd) { + StatusBarNoHunBehavior.assertInLegacyMode(); mIsolatedIconForAnimation = icon != null ? icon : mIsolatedIcon; mIsolatedIconAnimationEndRunnable = onAnimationEnd; showIconIsolated(icon); } public void showIconIsolated(StatusBarIconView icon) { + StatusBarNoHunBehavior.assertInLegacyMode(); mIsolatedIcon = icon; updateState(); } public void setIsolatedIconLocation(Rect isolatedIconLocation, boolean requireUpdate) { + StatusBarNoHunBehavior.assertInLegacyMode(); mIsolatedIconLocation = isolatedIconLocation; if (requireUpdate) { updateState(); @@ -794,7 +801,7 @@ public class NotificationIconContainer extends ViewGroup { animationProperties.setDuration(CANNED_ANIMATION_DURATION); animate = true; } - if (mIsolatedIconForAnimation != null) { + if (!StatusBarNoHunBehavior.isEnabled() && mIsolatedIconForAnimation != null) { if (view == mIsolatedIconForAnimation) { animationProperties = UNISOLATION_PROPERTY; animationProperties.setDelay( @@ -843,6 +850,7 @@ public class NotificationIconContainer extends ViewGroup { @Nullable private Consumer<Property> getEndAction() { + if (StatusBarNoHunBehavior.isEnabled()) return null; if (mIsolatedIconAnimationEndRunnable == null) return null; final Runnable endRunnable = mIsolatedIconAnimationEndRunnable; return prop -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java index c47ed1722bb4..fcc3af6a2134 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java @@ -397,6 +397,13 @@ public class SystemUIDialog extends AlertDialog implements ViewRootImpl.ConfigCh public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mDelegate.onWindowFocusChanged(this, hasFocus); + if (hasFocus) { + // Update SysUI state to reflect that a dialog is showing. This ensures the state is + // correct when this dialog regains focus after another dialog was closed. + // See b/386871258 + mSysUiState.setFlag(QuickStepContract.SYSUI_STATE_DIALOG_SHOWING, true) + .commitUpdate(mContext.getDisplayId()); + } } public void setShowForAllUsers(boolean show) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 1f1be261a854..c541cff4448c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -65,6 +65,7 @@ import com.android.systemui.statusbar.data.repository.StatusBarConfigurationCont import com.android.systemui.statusbar.disableflags.DisableFlagsLogger; import com.android.systemui.statusbar.events.SystemStatusAnimationCallback; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior; import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder; import com.android.systemui.statusbar.phone.NotificationIconContainer; import com.android.systemui.statusbar.phone.PhoneStatusBarView; @@ -676,6 +677,11 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue boolean headsUpVisible = mHomeStatusBarComponent .getHeadsUpAppearanceController() .shouldHeadsUpStatusBarBeVisible(); + if (StatusBarNoHunBehavior.isEnabled()) { + // With this flag enabled, we have no custom HUN behavior, so just always consider it + // to be not visible. + headsUpVisible = false; + } if (SceneContainerFlag.isEnabled()) { // With the scene container, only use the value calculated by the view model to diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index 4eb69babfadb..a29934fa3a16 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -39,6 +39,7 @@ import com.android.systemui.statusbar.chips.ui.view.ChipChronometer import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel import com.android.systemui.statusbar.notification.shared.ActiveNotificationModel import com.android.systemui.statusbar.notification.shared.CallType import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository @@ -159,6 +160,7 @@ constructor( notificationIconView = currentInfo.notificationIconView, intent = currentInfo.intent, notificationKey = currentInfo.key, + promotedContent = currentInfo.promotedContent, ) } else { return OngoingCallModel.NoCall @@ -215,6 +217,7 @@ constructor( notifModel.statusBarChipIconView, notifModel.contentIntent, notifModel.uid, + notifModel.promotedContent, isOngoing = true, statusBarSwipedAway = callNotificationInfo?.statusBarSwipedAway ?: false, ) @@ -334,6 +337,11 @@ constructor( val notificationIconView: StatusBarIconView?, val intent: PendingIntent?, val uid: Int, + /** + * If the call notification also meets promoted notification criteria, this field is filled + * in with the content related to promotion. Otherwise null. + */ + val promotedContent: PromotedNotificationContentModel?, /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */ val isOngoing: Boolean, /** True if the user has swiped away the status bar while in this phone call. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt index 2ab2b68bbb2e..9f8b45578903 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/StatusBarChipsModernization.kt @@ -1,18 +1,18 @@ /* -* 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. -*/ + * 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.ongoingcall import com.android.systemui.Flags @@ -44,9 +44,16 @@ object StatusBarChipsModernization { RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME) /** + * Called to ensure code is only run when the flag is enabled. This will throw an exception if + * the flag is not enabled to ensure that the refactor author catches issues in testing. + */ + @JvmStatic + inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, FLAG_NAME) + + /** * Called to ensure code is only run when the flag is disabled. This will throw an exception if * the flag is enabled to ensure that the refactor author catches issues in testing. */ @JvmStatic inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME) -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt index 2bfbf4826053..99141f592a2e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractor.kt @@ -165,6 +165,7 @@ constructor( notificationIconView = model.statusBarChipIconView, intent = model.contentIntent, notificationKey = model.key, + promotedContent = model.promotedContent, ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt index 1a5dcc16f3db..7d00e9d58e5b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone.ongoingcall.shared.model import android.app.PendingIntent import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel /** Represents the state of any ongoing calls. */ sealed interface OngoingCallModel { @@ -25,8 +26,8 @@ sealed interface OngoingCallModel { data object NoCall : OngoingCallModel /** - * There is an ongoing call but the call app is currently visible, so we don't need to show - * the chip. + * There is an ongoing call but the call app is currently visible, so we don't need to show the + * chip. */ data object InCallWithVisibleApp : OngoingCallModel @@ -41,11 +42,14 @@ sealed interface OngoingCallModel { * @property notificationIconView the [android.app.Notification.getSmallIcon] that's set on the * call notification. We may use this icon in the chip instead of the default phone icon. * @property intent the intent associated with the call notification. + * @property promotedContent if the call notification also meets promoted notification criteria, + * this field is filled in with the content related to promotion. Otherwise null. */ data class InCall( val startTimeMs: Long, val notificationIconView: StatusBarIconView?, val intent: PendingIntent?, val notificationKey: String, + val promotedContent: PromotedNotificationContentModel?, ) : OngoingCallModel } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt index b32037992501..dacb859967e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryImpl.kt @@ -111,7 +111,12 @@ constructor( pw.println("Carrier configs by subId") configs.keyIterator().forEach { pw.println(" subId=$it") - pw.println(" config=${configs.get(it).toStringConsideringDefaults()}") + val config = configs.get(it) + if (config == null) { + pw.println(" config=null (config was removed during dump)") + } else { + pw.println(" config=${config.toStringConsideringDefaults()}") + } } // Finally, print the default config pw.println("Default config:") diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt index 8daa8037c367..7e76d77abe61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt @@ -41,8 +41,8 @@ import com.android.systemui.statusbar.notification.icon.ui.viewbinder.ConnectedD import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization +import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel -import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel import javax.inject.Inject import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt index b1cc208e9b43..9c1171fd1ebc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt @@ -57,6 +57,7 @@ import com.android.systemui.statusbar.phone.ui.StatusBarIconController import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarIconBlockListBinder import com.android.systemui.statusbar.pipeline.shared.ui.binder.HomeStatusBarViewBinder import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener +import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.HomeStatusBarViewModelFactory import javax.inject.Inject @@ -304,11 +305,7 @@ fun StatusBarRoot( fun Disambiguation(viewModel: HomeStatusBarViewModel) { val clockVisibilityModel = viewModel.isClockVisible.collectAsStateWithLifecycle( - initialValue = - HomeStatusBarViewModel.VisibilityModel( - visibility = View.GONE, - shouldAnimateChange = false, - ) + initialValue = VisibilityModel(visibility = View.GONE, shouldAnimateChange = false) ) if (clockVisibilityModel.value.visibility == View.VISIBLE) { Box(modifier = Modifier.fillMaxSize().alpha(0.5f), contentAlignment = Alignment.Center) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/SystemInfoCombinedVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/SystemInfoCombinedVisibilityModel.kt new file mode 100644 index 000000000000..e27225270633 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/SystemInfoCombinedVisibilityModel.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared.ui.model + +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger +import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState + +/** The combined visibility + animation state for the system info status bar area */ +data class SystemInfoCombinedVisibilityModel( + val baseVisibility: VisibilityModel, + val animationState: SystemEventAnimationState, +) : Diffable<SystemInfoCombinedVisibilityModel> { + override fun logDiffs(prevVal: SystemInfoCombinedVisibilityModel, row: TableRowLogger) { + if (animationState != prevVal.animationState) { + row.logChange(COL_ANIM, animationState.name) + } + + baseVisibility.logDiffs(prevVal.baseVisibility, row) + } + + override fun logFull(row: TableRowLogger) { + row.logChange(COL_ANIM, animationState.name) + baseVisibility.logFull(row) + } + + companion object { + const val COL_ANIM = "animState" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/VisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/VisibilityModel.kt new file mode 100644 index 000000000000..7b39ada72c64 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/VisibilityModel.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.shared.ui.model + +import android.view.View +import com.android.systemui.log.table.Diffable +import com.android.systemui.log.table.TableRowLogger +import com.android.systemui.util.visibilityString + +/** Models the current visibility for a specific child view of status bar. */ +data class VisibilityModel( + @View.Visibility val visibility: Int, + /** True if a visibility change should be animated. */ + val shouldAnimateChange: Boolean, +) : Diffable<VisibilityModel> { + override fun logDiffs(prevVal: VisibilityModel, row: TableRowLogger) { + if (visibility != prevVal.visibility) { + row.logChange(COL_VIS, visibilityString(visibility)) + } + + if (shouldAnimateChange != prevVal.shouldAnimateChange) { + row.logChange(COL_ANIMATE, shouldAnimateChange) + } + } + + override fun logFull(row: TableRowLogger) { + row.logChange(COL_VIS, visibilityString(visibility)) + row.logChange(COL_ANIMATE, shouldAnimateChange) + } + + companion object { + const val COL_VIS = "vis" + const val COL_ANIMATE = "animate" + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt index 6ff4354fcc46..5acedf129184 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt @@ -28,6 +28,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.GONE import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.log.table.TableLogBufferFactory +import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor @@ -39,10 +41,10 @@ import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChip import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel import com.android.systemui.statusbar.events.domain.interactor.SystemStatusEventAnimationInteractor -import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationState.Idle import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel import com.android.systemui.statusbar.featurepods.popups.ui.viewmodel.StatusBarPopupChipsViewModel +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.layout.ui.viewmodel.StatusBarContentInsetsViewModelStore import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor @@ -52,7 +54,8 @@ import com.android.systemui.statusbar.phone.domain.interactor.DarkIconInteractor import com.android.systemui.statusbar.phone.domain.interactor.LightsOutInteractor import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarIconBlockListInteractor import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarInteractor -import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel.VisibilityModel +import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel +import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -154,19 +157,6 @@ interface HomeStatusBarViewModel { */ val areaTint: Flow<StatusBarTintColor> - /** Models the current visibility for a specific child view of status bar. */ - data class VisibilityModel( - @View.Visibility val visibility: Int, - /** True if a visibility change should be animated. */ - val shouldAnimateChange: Boolean, - ) - - /** The combined visibility + animation state for the system info status bar area */ - data class SystemInfoCombinedVisibilityModel( - val baseVisibility: VisibilityModel, - val animationState: SystemEventAnimationState, - ) - /** Interface for the assisted factory, to allow for providing a fake in tests */ interface HomeStatusBarViewModelFactory { fun create(displayId: Int): HomeStatusBarViewModel @@ -177,6 +167,7 @@ class HomeStatusBarViewModelImpl @AssistedInject constructor( @Assisted thisDisplayId: Int, + tableLoggerFactory: TableLogBufferFactory, homeStatusBarInteractor: HomeStatusBarInteractor, homeStatusBarIconBlockListInteractor: HomeStatusBarIconBlockListInteractor, lightsOutInteractor: LightsOutInteractor, @@ -195,9 +186,19 @@ constructor( statusBarContentInsetsViewModelStore: StatusBarContentInsetsViewModelStore, @Application coroutineScope: CoroutineScope, ) : HomeStatusBarViewModel { + + val tableLogger = tableLoggerFactory.getOrCreate(tableLogBufferName(thisDisplayId), 200) + override val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean> = keyguardTransitionInteractor .isInTransition(Edge.create(from = LOCKSCREEN, to = OCCLUDED)) + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = "", + columnName = COL_LOCK_TO_OCCLUDED, + initialValue = false, + ) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false) override val transitionFromLockscreenToDreamStartedEvent: Flow<Unit> = @@ -224,20 +225,33 @@ constructor( // which lives elsewhere.) currentScene == Scenes.Gone || isOccluded } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = "", + columnName = COL_ALLOWED_BY_SCENE, + initialValue = false, + ) .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false) override val areNotificationsLightsOut: Flow<Boolean> = if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) { - emptyFlow() - } else { - combine( - notificationsInteractor.areAnyNotificationsPresent, - lightsOutInteractor.isLowProfile(thisDisplayId) ?: flowOf(false), - ) { hasNotifications, isLowProfile -> - hasNotifications && isLowProfile - } - .distinctUntilChanged() - } + emptyFlow() + } else { + combine( + notificationsInteractor.areAnyNotificationsPresent, + lightsOutInteractor.isLowProfile(thisDisplayId) ?: flowOf(false), + ) { hasNotifications, isLowProfile -> + hasNotifications && isLowProfile + } + .distinctUntilChanged() + } + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = "", + columnName = COL_NOTIF_LIGHTS_OUT, + initialValue = false, + ) override val areaTint: Flow<StatusBarTintColor> = darkIconInteractor @@ -276,19 +290,26 @@ constructor( override val shouldHomeStatusBarBeVisible = combine( - isHomeStatusBarAllowed, - keyguardInteractor.isSecureCameraActive, - headsUpNotificationInteractor.statusBarHeadsUpStatus, - ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState -> - // When launching the camera over the lockscreen, the status icons would typically - // become visible momentarily before animating out, since we're not yet aware that the - // launching camera activity is fullscreen. Even once the activity finishes launching, - // it takes a short time before WM decides that the top app wants to hide the icons and - // tells us to hide them. - // To ensure that this high-visibility animation is smooth, keep the icons hidden during - // a camera launch. See b/257292822. - headsUpState.isPinned || (isHomeStatusBarAllowed && !isSecureCameraActive) - } + isHomeStatusBarAllowed, + keyguardInteractor.isSecureCameraActive, + headsUpNotificationInteractor.statusBarHeadsUpStatus, + ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState -> + // When launching the camera over the lockscreen, the status icons would typically + // become visible momentarily before animating out, since we're not yet aware that + // the launching camera activity is fullscreen. Even once the activity finishes + // launching, it takes a short time before WM decides that the top app wants to hide + // the icons and tells us to hide them. To ensure that this high-visibility + // animation is smooth, keep the icons hidden during a camera launch. See + // b/257292822. + headsUpState.isPinned || (isHomeStatusBarAllowed && !isSecureCameraActive) + } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = "", + columnName = COL_VISIBLE, + initialValue = false, + ) private val isAnyChipVisible = if (StatusBarNotifChips.isEnabled) { @@ -297,54 +318,88 @@ constructor( primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Shown } } + /** + * True if we need to hide the usual start side content in order to show the heads up + * notification info. + */ + private val hideStartSideContentForHeadsUp: Flow<Boolean> = + if (StatusBarNoHunBehavior.isEnabled) { + flowOf(false) + } else { + headsUpNotificationInteractor.statusBarHeadsUpStatus.map { + it == PinnedStatus.PinnedBySystem + } + } + override val shouldShowOperatorNameView: Flow<Boolean> = combine( - shouldHomeStatusBarBeVisible, - headsUpNotificationInteractor.statusBarHeadsUpStatus, - homeStatusBarInteractor.visibilityViaDisableFlags, - homeStatusBarInteractor.shouldShowOperatorName, - ) { shouldStatusBarBeVisible, headsUpStatus, visibilityViaDisableFlags, shouldShowOperator - -> - val hideForHeadsUp = headsUpStatus == PinnedStatus.PinnedBySystem - shouldStatusBarBeVisible && - !hideForHeadsUp && - visibilityViaDisableFlags.isSystemInfoAllowed && - shouldShowOperator - } + shouldHomeStatusBarBeVisible, + hideStartSideContentForHeadsUp, + homeStatusBarInteractor.visibilityViaDisableFlags, + homeStatusBarInteractor.shouldShowOperatorName, + ) { + shouldStatusBarBeVisible, + hideStartSideContentForHeadsUp, + visibilityViaDisableFlags, + shouldShowOperator -> + shouldStatusBarBeVisible && + !hideStartSideContentForHeadsUp && + visibilityViaDisableFlags.isSystemInfoAllowed && + shouldShowOperator + } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = "", + columnName = COL_SHOW_OPERATOR_NAME, + initialValue = false, + ) override val isClockVisible: Flow<VisibilityModel> = combine( - shouldHomeStatusBarBeVisible, - headsUpNotificationInteractor.statusBarHeadsUpStatus, - homeStatusBarInteractor.visibilityViaDisableFlags, - ) { shouldStatusBarBeVisible, headsUpStatus, visibilityViaDisableFlags -> - val hideClockForHeadsUp = headsUpStatus == PinnedStatus.PinnedBySystem - val showClock = - shouldStatusBarBeVisible && - visibilityViaDisableFlags.isClockAllowed && - !hideClockForHeadsUp - // Always use View.INVISIBLE here, so that animations work - VisibilityModel(showClock.toVisibleOrInvisible(), visibilityViaDisableFlags.animate) - } + shouldHomeStatusBarBeVisible, + hideStartSideContentForHeadsUp, + homeStatusBarInteractor.visibilityViaDisableFlags, + ) { shouldStatusBarBeVisible, hideStartSideContentForHeadsUp, visibilityViaDisableFlags + -> + val showClock = + shouldStatusBarBeVisible && + visibilityViaDisableFlags.isClockAllowed && + !hideStartSideContentForHeadsUp + // Always use View.INVISIBLE here, so that animations work + VisibilityModel(showClock.toVisibleOrInvisible(), visibilityViaDisableFlags.animate) + } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = COL_PREFIX_CLOCK, + initialValue = VisibilityModel(false.toVisibleOrInvisible(), false), + ) override val isNotificationIconContainerVisible: Flow<VisibilityModel> = combine( - shouldHomeStatusBarBeVisible, - isAnyChipVisible, - homeStatusBarInteractor.visibilityViaDisableFlags, - ) { shouldStatusBarBeVisible, anyChipVisible, visibilityViaDisableFlags -> - val showNotificationIconContainer = - if (anyChipVisible) { - false - } else { - shouldStatusBarBeVisible && - visibilityViaDisableFlags.areNotificationIconsAllowed - } - VisibilityModel( - showNotificationIconContainer.toVisibleOrGone(), - visibilityViaDisableFlags.animate, + shouldHomeStatusBarBeVisible, + isAnyChipVisible, + homeStatusBarInteractor.visibilityViaDisableFlags, + ) { shouldStatusBarBeVisible, anyChipVisible, visibilityViaDisableFlags -> + val showNotificationIconContainer = + if (anyChipVisible) { + false + } else { + shouldStatusBarBeVisible && + visibilityViaDisableFlags.areNotificationIconsAllowed + } + VisibilityModel( + showNotificationIconContainer.toVisibleOrGone(), + visibilityViaDisableFlags.animate, + ) + } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = COL_PREFIX_NOTIF_CONTAINER, + initialValue = VisibilityModel(false.toVisibleOrInvisible(), false), ) - } private val isSystemInfoVisible = combine(shouldHomeStatusBarBeVisible, homeStatusBarInteractor.visibilityViaDisableFlags) { @@ -357,18 +412,19 @@ constructor( override val systemInfoCombinedVis = combine(isSystemInfoVisible, animations.animationState) { sysInfoVisible, animationState -> - HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( - sysInfoVisible, - animationState, - ) + SystemInfoCombinedVisibilityModel(sysInfoVisible, animationState) } + .distinctUntilChanged() + .logDiffsForTable( + tableLogBuffer = tableLogger, + columnPrefix = COL_PREFIX_SYSTEM_INFO, + initialValue = + SystemInfoCombinedVisibilityModel(VisibilityModel(View.VISIBLE, false), Idle), + ) .stateIn( coroutineScope, SharingStarted.WhileSubscribed(), - HomeStatusBarViewModel.SystemInfoCombinedVisibilityModel( - VisibilityModel(View.VISIBLE, false), - Idle, - ), + SystemInfoCombinedVisibilityModel(VisibilityModel(View.VISIBLE, false), Idle), ) override val iconBlockList: Flow<List<String>> = @@ -393,6 +449,19 @@ constructor( HomeStatusBarViewModel.HomeStatusBarViewModelFactory { override fun create(displayId: Int): HomeStatusBarViewModelImpl } + + companion object { + private const val COL_LOCK_TO_OCCLUDED = "Lock->Occluded" + private const val COL_ALLOWED_BY_SCENE = "allowedByScene" + private const val COL_NOTIF_LIGHTS_OUT = "notifLightsOut" + private const val COL_SHOW_OPERATOR_NAME = "showOperatorName" + private const val COL_VISIBLE = "visible" + private const val COL_PREFIX_CLOCK = "clock" + private const val COL_PREFIX_NOTIF_CONTAINER = "notifContainer" + private const val COL_PREFIX_SYSTEM_INFO = "systemInfo" + + fun tableLogBufferName(displayId: Int) = "HomeStatusBarViewModel[$displayId]" + } } /** Lookup the color for a given view in the status bar */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt index cb26679434ef..520c5632370b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt @@ -408,6 +408,11 @@ constructor( action.extras.getBoolean(Notification.Action.EXTRA_IS_MAGIC, false) ) { background = MagicActionBackgroundDrawable(parent.context) + val textColor = + parent.context.getColor( + com.android.internal.R.color.materialColorOnPrimaryContainer + ) + setTextColor(textColor) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt index fdc2d8d96f9b..5fa15b831299 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt @@ -43,6 +43,7 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -123,12 +124,20 @@ constructor( * explicitly wants a shortcut to DND). Please prefer using [modes] or [activeModes] in all * other scenarios. */ - val dndMode: StateFlow<ZenMode?> by lazy { - ModesUi.assertInNewMode() - zenModeRepository.modes - .map { modes -> modes.singleOrNull { it.isManualDnd } } - .stateIn(scope = backgroundScope, started = SharingStarted.Eagerly, initialValue = null) - } + val dndMode: StateFlow<ZenMode?> = + if (ModesUi.isEnabled) + zenModeRepository.modes + .map { modes -> modes.singleOrNull { it.isManualDnd } } + .stateIn( + scope = backgroundScope, + started = SharingStarted.Eagerly, + initialValue = null, + ) + else MutableStateFlow<ZenMode?>(null) + get() { + ModesUi.assertInNewMode() + return field + } /** Flow returning the currently active mode(s), if any. */ val activeModes: Flow<ActiveZenModes> = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt index 9ff0d18f0e2b..db5f1301823b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegate.kt @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.policy.ui.dialog +import android.app.Dialog +import android.content.Context import android.content.Intent import android.provider.Settings import android.util.Log @@ -36,6 +38,7 @@ import com.android.compose.PlatformOutlinedButton import com.android.compose.theme.PlatformTheme import com.android.internal.annotations.VisibleForTesting import com.android.internal.jank.InteractionJankMonitor +import com.android.settingslib.notification.modes.EnableDndDialogFactory import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator import com.android.systemui.animation.Expandable @@ -43,6 +46,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dialog.ui.composable.AlertDialogContent import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.qs.tiles.dialog.QSEnableDndDialogMetricsLogger import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor import com.android.systemui.statusbar.phone.ComponentSystemUIDialog @@ -61,6 +65,7 @@ import kotlinx.coroutines.withContext class ModesDialogDelegate @Inject constructor( + val context: Context, private val sysuiDialogFactory: SystemUIDialogFactory, private val dialogTransitionAnimator: DialogTransitionAnimator, private val activityStarter: ActivityStarter, @@ -72,6 +77,7 @@ constructor( ) : SystemUIDialog.Delegate { // NOTE: This should only be accessed/written from the main thread. @VisibleForTesting var currentDialog: ComponentSystemUIDialog? = null + private val dndDurationDialogLogger by lazy { QSEnableDndDialogMetricsLogger(context) } override fun createDialog(): SystemUIDialog { Assert.isMainThread() @@ -195,6 +201,26 @@ constructor( activityStarter.startActivity(intent, /* dismissShade= */ true, animationController) } + /** + * Special dialog to ask the user for the duration of DND. Not to be confused with the modes + * dialog itself. + */ + fun makeDndDurationDialog(): Dialog { + val dialog = + EnableDndDialogFactory( + context, + R.style.Theme_SystemUI_Dialog, + /* cancelIsNeutral= */ true, + dndDurationDialogLogger, + ) + .createDialog() + SystemUIDialog.applyFlags(dialog) + SystemUIDialog.setShowForAllUsers(dialog, true) + SystemUIDialog.registerDismissListener(dialog) + SystemUIDialog.setDialogSize(dialog) + return dialog + } + companion object { private const val TAG = "ModesDialogDelegate" private val ZEN_MODE_SETTINGS_INTENT = Intent(Settings.ACTION_ZEN_MODE_SETTINGS) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt index 1c13a833ef30..07f1c3470c83 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ui/dialog/viewmodel/ModesDialogViewModel.kt @@ -16,20 +16,16 @@ package com.android.systemui.statusbar.policy.ui.dialog.viewmodel -import android.app.Dialog import android.content.Context import android.content.Intent import android.provider.Settings.ACTION_AUTOMATIC_ZEN_RULE_SETTINGS import android.provider.Settings.EXTRA_AUTOMATIC_ZEN_RULE_ID -import com.android.settingslib.notification.modes.EnableZenModeDialog import com.android.settingslib.notification.modes.ZenMode import com.android.settingslib.notification.modes.ZenModeDescriptions import com.android.systemui.common.shared.model.asIcon import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.qs.tiles.dialog.QSZenModeDialogMetricsLogger import com.android.systemui.res.R -import com.android.systemui.statusbar.phone.SystemUIDialog import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger @@ -54,7 +50,6 @@ constructor( private val dialogDelegate: ModesDialogDelegate, private val dialogEventLogger: ModesDialogEventLogger, ) { - private val zenDialogMetricsLogger = QSZenModeDialogMetricsLogger(context) private val zenModeDescriptions = ZenModeDescriptions(context) // Modes that should be displayed in the dialog @@ -112,7 +107,7 @@ constructor( if (zenModeInteractor.shouldAskForZenDuration(mode)) { dialogEventLogger.logOpenDurationDialog(mode) // NOTE: The dialog handles turning on the mode itself. - val dialog = makeZenModeDialog() + val dialog = dialogDelegate.makeDndDurationDialog() dialog.show() } else { dialogEventLogger.logModeOn(mode) @@ -173,20 +168,4 @@ constructor( modeDescription ?: context.getString(R.string.zen_mode_off) } } - - private fun makeZenModeDialog(): Dialog { - val dialog = - EnableZenModeDialog( - context, - R.style.Theme_SystemUI_Dialog, - /* cancelIsNeutral= */ true, - zenDialogMetricsLogger, - ) - .createDialog() - SystemUIDialog.applyFlags(dialog) - SystemUIDialog.setShowForAllUsers(dialog, true) - SystemUIDialog.registerDismissListener(dialog) - SystemUIDialog.setDialogSize(dialog) - return dialog - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt index a98a9e0c16d2..12ef68dafa64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt @@ -24,6 +24,7 @@ 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.domain.interactor.KeyguardStatusBarInteractor +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback @@ -59,7 +60,7 @@ constructor( ) { private val showingHeadsUpStatusBar: Flow<Boolean> = - if (SceneContainerFlag.isEnabled) { + if (SceneContainerFlag.isEnabled && !StatusBarNoHunBehavior.isEnabled) { headsUpNotificationInteractor.statusBarHeadsUpStatus.map { it.isPinned } } else { flowOf(false) diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt index c43f31beb5bc..a2125c8f0955 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/TouchpadTutorialModule.kt @@ -39,6 +39,8 @@ import com.android.systemui.touchpad.tutorial.ui.viewmodel.HomeGestureRecognizer import com.android.systemui.touchpad.tutorial.ui.viewmodel.HomeGestureScreenViewModel import com.android.systemui.touchpad.tutorial.ui.viewmodel.RecentAppsGestureRecognizerProvider import com.android.systemui.touchpad.tutorial.ui.viewmodel.RecentAppsGestureScreenViewModel +import com.android.systemui.touchpad.tutorial.ui.viewmodel.SwitchAppsGestureRecognizerProvider +import com.android.systemui.touchpad.tutorial.ui.viewmodel.SwitchAppsGestureScreenViewModel import dagger.Binds import dagger.Module import dagger.Provides @@ -69,6 +71,14 @@ interface TouchpadTutorialModule { } @Provides + fun switchAppsViewModel( + recognizerProvider: SwitchAppsGestureRecognizerProvider, + adapterFactory: GestureRecognizerAdapter.Factory, + ): SwitchAppsGestureScreenViewModel { + return SwitchAppsGestureScreenViewModel(adapterFactory.create(recognizerProvider)) + } + + @Provides fun recentAppsViewModel( recognizerProvider: RecentAppsGestureRecognizerProvider, adapterFactory: GestureRecognizerAdapter.Factory, diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt new file mode 100644 index 000000000000..3bb0dd779613 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/SwitchAppsGestureTutorialScreen.kt @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2025 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.touchpad.tutorial.ui.composable + +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import com.airbnb.lottie.compose.rememberLottieDynamicProperties +import com.android.compose.theme.LocalAndroidColorScheme +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialScreenConfig +import com.android.systemui.inputdevice.tutorial.ui.composable.rememberColorFilterProperty +import com.android.systemui.res.R +import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel +import com.android.systemui.touchpad.tutorial.ui.viewmodel.SwitchAppsGestureScreenViewModel + +@Composable +fun SwitchAppsGestureTutorialScreen( + viewModel: SwitchAppsGestureScreenViewModel, + easterEggGestureViewModel: EasterEggGestureViewModel, + onDoneButtonClicked: () -> Unit, + onBack: () -> Unit, +) { + val screenConfig = + TutorialScreenConfig( + colors = rememberScreenColors(), + strings = + TutorialScreenConfig.Strings( + titleResId = R.string.touchpad_switch_apps_gesture_action_title, + bodyResId = R.string.touchpad_switch_apps_gesture_guidance, + titleSuccessResId = R.string.touchpad_switch_apps_gesture_success_title, + bodySuccessResId = R.string.touchpad_switch_apps_gesture_success_body, + titleErrorResId = R.string.gesture_error_title, + bodyErrorResId = R.string.touchpad_switch_gesture_error_body, + ), + // TODO: replace animation + animations = TutorialScreenConfig.Animations(educationResId = R.raw.trackpad_back_edu), + ) + GestureTutorialScreen( + screenConfig = screenConfig, + tutorialStateFlow = viewModel.tutorialState, + motionEventConsumer = { + easterEggGestureViewModel.accept(it) + viewModel.handleEvent(it) + }, + easterEggTriggeredFlow = easterEggGestureViewModel.easterEggTriggered, + onEasterEggFinished = easterEggGestureViewModel::onEasterEggFinished, + onDoneButtonClicked = onDoneButtonClicked, + onBack = onBack, + ) +} + +@Composable +private fun rememberScreenColors(): TutorialScreenConfig.Colors { + val onTertiary = MaterialTheme.colorScheme.onTertiary + val onTertiaryFixed = LocalAndroidColorScheme.current.onTertiaryFixed + val onTertiaryFixedVariant = LocalAndroidColorScheme.current.onTertiaryFixedVariant + val tertiaryFixedDim = LocalAndroidColorScheme.current.tertiaryFixedDim + val dynamicProperties = + rememberLottieDynamicProperties( + rememberColorFilterProperty(".tertiaryFixedDim", tertiaryFixedDim), + rememberColorFilterProperty(".onTertiaryFixed", onTertiaryFixed), + rememberColorFilterProperty(".onTertiary", onTertiary), + rememberColorFilterProperty(".onTertiaryFixedVariant", onTertiaryFixedVariant), + ) + val screenColors = + remember(dynamicProperties) { + TutorialScreenConfig.Colors( + background = onTertiaryFixed, + title = tertiaryFixedDim, + animationColors = dynamicProperties, + ) + } + return screenColors +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt index c8a58400069e..69b7e892a380 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/composable/TutorialSelectionScreen.kt @@ -61,6 +61,7 @@ fun TutorialSelectionScreen( onBackTutorialClicked: () -> Unit, onHomeTutorialClicked: () -> Unit, onRecentAppsTutorialClicked: () -> Unit, + onSwitchAppsTutorialClicked: () -> Unit, onDoneButtonClicked: () -> Unit, lastSelectedScreen: Screen, ) { @@ -86,6 +87,7 @@ fun TutorialSelectionScreen( onBackTutorialClicked = onBackTutorialClicked, onHomeTutorialClicked = onHomeTutorialClicked, onRecentAppsTutorialClicked = onRecentAppsTutorialClicked, + onSwitchAppsTutorialClicked = onSwitchAppsTutorialClicked, modifier = Modifier.weight(1f).padding(60.dp), lastSelectedScreen, ) @@ -95,6 +97,7 @@ fun TutorialSelectionScreen( onBackTutorialClicked = onBackTutorialClicked, onHomeTutorialClicked = onHomeTutorialClicked, onRecentAppsTutorialClicked = onRecentAppsTutorialClicked, + onSwitchAppsTutorialClicked = onSwitchAppsTutorialClicked, modifier = Modifier.weight(1f).padding(60.dp), lastSelectedScreen, ) @@ -113,6 +116,7 @@ private fun HorizontalSelectionButtons( onBackTutorialClicked: () -> Unit, onHomeTutorialClicked: () -> Unit, onRecentAppsTutorialClicked: () -> Unit, + onSwitchAppsTutorialClicked: () -> Unit, modifier: Modifier = Modifier, lastSelectedScreen: Screen, ) { @@ -121,10 +125,11 @@ private fun HorizontalSelectionButtons( verticalAlignment = Alignment.CenterVertically, modifier = modifier, ) { - ThreeTutorialButtons( + FourTutorialButtons( onBackTutorialClicked, onHomeTutorialClicked, onRecentAppsTutorialClicked, + onSwitchAppsTutorialClicked, modifier = Modifier.weight(1f).fillMaxSize(), lastSelectedScreen, ) @@ -136,6 +141,7 @@ private fun VerticalSelectionButtons( onBackTutorialClicked: () -> Unit, onHomeTutorialClicked: () -> Unit, onRecentAppsTutorialClicked: () -> Unit, + onSwitchAppsTutorialClicked: () -> Unit, modifier: Modifier = Modifier, lastSelectedScreen: Screen, ) { @@ -144,10 +150,11 @@ private fun VerticalSelectionButtons( horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier, ) { - ThreeTutorialButtons( + FourTutorialButtons( onBackTutorialClicked, onHomeTutorialClicked, onRecentAppsTutorialClicked, + onSwitchAppsTutorialClicked, modifier = Modifier.weight(1f).fillMaxSize(), lastSelectedScreen, ) @@ -155,21 +162,24 @@ private fun VerticalSelectionButtons( } @Composable -private fun ThreeTutorialButtons( +private fun FourTutorialButtons( onBackTutorialClicked: () -> Unit, onHomeTutorialClicked: () -> Unit, onRecentAppsTutorialClicked: () -> Unit, + onSwitchAppsTutorialClicked: () -> Unit, modifier: Modifier = Modifier, lastSelectedScreen: Screen, ) { val homeFocusRequester = remember { FocusRequester() } val backFocusRequester = remember { FocusRequester() } val recentAppsFocusRequester = remember { FocusRequester() } + val switchAppsFocusRequester = remember { FocusRequester() } LaunchedEffect(Unit) { when (lastSelectedScreen) { Screen.HOME_GESTURE -> homeFocusRequester.requestFocus() Screen.BACK_GESTURE -> backFocusRequester.requestFocus() Screen.RECENT_APPS_GESTURE -> recentAppsFocusRequester.requestFocus() + Screen.SWITCH_APPS_GESTURE -> switchAppsFocusRequester.requestFocus() else -> {} // No-Op. } } @@ -197,6 +207,14 @@ private fun ThreeTutorialButtons( backgroundColor = MaterialTheme.colorScheme.secondary, modifier = modifier.focusRequester(recentAppsFocusRequester).focusable(), ) + TutorialButton( + text = stringResource(R.string.touchpad_tutorial_switch_apps_gesture_button), + icon = ImageVector.vectorResource(id = R.drawable.touchpad_tutorial_apps_icon), + iconColor = MaterialTheme.colorScheme.primary, + onClick = onSwitchAppsTutorialClicked, + backgroundColor = MaterialTheme.colorScheme.onPrimary, + modifier = modifier.focusRequester(switchAppsFocusRequester).focusable(), + ) } @Composable @@ -227,7 +245,7 @@ private fun TutorialButton( tint = iconColor, ) Spacer(modifier = Modifier.height(16.dp)) - Text(text = text, style = MaterialTheme.typography.headlineLarge) + Text(text = text, style = MaterialTheme.typography.headlineLarge, color = iconColor) } } } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt new file mode 100644 index 000000000000..470048bd3b20 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/SwitchAppsGestureRecognizer.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2025 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.touchpad.tutorial.ui.gesture + +import android.view.MotionEvent + +// TODO: javadoc +class SwitchAppsGestureRecognizer(private val gestureDistanceThresholdPx: Int) : GestureRecognizer { + + private val distanceTracker = DistanceTracker() + private var gestureStateChangedCallback: (GestureState) -> Unit = {} + + override fun addGestureStateCallback(callback: (GestureState) -> Unit) { + gestureStateChangedCallback = callback + } + + override fun clearGestureStateCallback() { + gestureStateChangedCallback = {} + } + + // TODO: recognizer logic + override fun accept(event: MotionEvent) { + if (!isMultifingerTouchpadSwipe(event)) return + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt index 3264300ed908..0a139125afa2 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt @@ -37,6 +37,7 @@ import com.android.systemui.res.R import com.android.systemui.touchpad.tutorial.ui.composable.BackGestureTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.HomeGestureTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.RecentAppsGestureTutorialScreen +import com.android.systemui.touchpad.tutorial.ui.composable.SwitchAppsGestureTutorialScreen import com.android.systemui.touchpad.tutorial.ui.composable.TutorialSelectionScreen import com.android.systemui.touchpad.tutorial.ui.viewmodel.BackGestureScreenViewModel import com.android.systemui.touchpad.tutorial.ui.viewmodel.EasterEggGestureViewModel @@ -45,7 +46,9 @@ import com.android.systemui.touchpad.tutorial.ui.viewmodel.RecentAppsGestureScre import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.BACK_GESTURE import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.HOME_GESTURE import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.RECENT_APPS_GESTURE +import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.SWITCH_APPS_GESTURE import com.android.systemui.touchpad.tutorial.ui.viewmodel.Screen.TUTORIAL_SELECTION +import com.android.systemui.touchpad.tutorial.ui.viewmodel.SwitchAppsGestureScreenViewModel import com.android.systemui.touchpad.tutorial.ui.viewmodel.TouchpadTutorialViewModel import javax.inject.Inject @@ -58,6 +61,7 @@ constructor( private val backGestureViewModel: BackGestureScreenViewModel, private val homeGestureViewModel: HomeGestureScreenViewModel, private val recentAppsGestureViewModel: RecentAppsGestureScreenViewModel, + private val switchAppsGestureScreenViewModel: SwitchAppsGestureScreenViewModel, private val easterEggGestureViewModel: EasterEggGestureViewModel, ) : ComponentActivity() { @@ -75,6 +79,7 @@ constructor( backGestureViewModel, homeGestureViewModel, recentAppsGestureViewModel, + switchAppsGestureScreenViewModel, easterEggGestureViewModel, closeTutorial = ::finishTutorial, ) @@ -108,6 +113,7 @@ fun TouchpadTutorialScreen( backGestureViewModel: BackGestureScreenViewModel, homeGestureViewModel: HomeGestureScreenViewModel, recentAppsGestureViewModel: RecentAppsGestureScreenViewModel, + switchAppsGestureScreenViewModel: SwitchAppsGestureScreenViewModel, easterEggGestureViewModel: EasterEggGestureViewModel, closeTutorial: () -> Unit, ) { @@ -128,6 +134,10 @@ fun TouchpadTutorialScreen( lastSelectedScreen = RECENT_APPS_GESTURE vm.goTo(RECENT_APPS_GESTURE) }, + onSwitchAppsTutorialClicked = { + lastSelectedScreen = SWITCH_APPS_GESTURE + vm.goTo(SWITCH_APPS_GESTURE) + }, onDoneButtonClicked = closeTutorial, lastSelectedScreen, ) @@ -152,5 +162,12 @@ fun TouchpadTutorialScreen( onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) }, onBack = { vm.goTo(TUTORIAL_SELECTION) }, ) + SWITCH_APPS_GESTURE -> + SwitchAppsGestureTutorialScreen( + switchAppsGestureScreenViewModel, + easterEggGestureViewModel, + onDoneButtonClicked = { vm.goTo(SWITCH_APPS_GESTURE) }, + onBack = { vm.goTo(TUTORIAL_SELECTION) }, + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt new file mode 100644 index 000000000000..b1e163b55377 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureRecognizerProvider.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2025 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.touchpad.tutorial.ui.viewmodel + +import com.android.systemui.touchpad.tutorial.ui.gesture.GestureRecognizer +import com.android.systemui.touchpad.tutorial.ui.gesture.SwitchAppsGestureRecognizer +import com.android.systemui.touchpad.tutorial.ui.gesture.VelocityTracker +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class SwitchAppsGestureRecognizerProvider +@Inject +constructor(val resources: TouchpadGestureResources, val velocityTracker: VelocityTracker) : + GestureRecognizerProvider { + + override val recognizer: Flow<GestureRecognizer> = + resources.distanceThreshold().map { + SwitchAppsGestureRecognizer(gestureDistanceThresholdPx = it) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt new file mode 100644 index 000000000000..6593db49745d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/SwitchAppsGestureScreenViewModel.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2025 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.touchpad.tutorial.ui.viewmodel + +import android.view.MotionEvent +import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState +import com.android.systemui.res.R +import com.android.systemui.touchpad.tutorial.ui.gesture.handleTouchpadMotionEvent +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class SwitchAppsGestureScreenViewModel(private val gestureRecognizer: GestureRecognizerAdapter) : + TouchpadTutorialScreenViewModel { + + // TODO: replace with correct markers and resource + override val tutorialState: Flow<TutorialActionState> = + gestureRecognizer.gestureState + .map { + it to + TutorialAnimationProperties( + progressStartMarker = "drag with gesture", + progressEndMarker = "onPause", + successAnimation = R.raw.trackpad_recent_apps_success, + ) + } + .mapToTutorialState() + + override fun handleEvent(event: MotionEvent): Boolean { + return gestureRecognizer.handleTouchpadMotionEvent(event) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt index c56dcf3bf062..c6d5e7ad0a71 100644 --- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/viewmodel/TouchpadTutorialViewModel.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.StateFlow class TouchpadTutorialViewModel( private val gesturesInteractor: TouchpadGesturesInteractor, - private val logger: InputDeviceTutorialLogger + private val logger: InputDeviceTutorialLogger, ) : ViewModel() { private val _screen = MutableStateFlow(Screen.TUTORIAL_SELECTION) @@ -50,7 +50,7 @@ class TouchpadTutorialViewModel( @Inject constructor( private val gesturesInteractor: TouchpadGesturesInteractor, - private val logger: InputDeviceTutorialLogger + private val logger: InputDeviceTutorialLogger, ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") @@ -65,4 +65,5 @@ enum class Screen { BACK_GESTURE, HOME_GESTURE, RECENT_APPS_GESTURE, + SWITCH_APPS_GESTURE, } diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt index 07c4de0ac0c4..b0d6d62289c7 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModel.kt @@ -35,6 +35,7 @@ import com.android.systemui.res.R import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onConfigChanged +import com.android.systemui.util.time.SystemClock import com.android.systemui.volume.Events import com.android.systemui.volume.dialog.dagger.scope.VolumeDialog import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope @@ -56,6 +57,7 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +private const val DRAWER_STATE_ANIMATION_DURATION = 400L private const val SHOW_RINGER_TOAST_COUNT = 12 @VolumeDialogScope @@ -71,6 +73,7 @@ constructor( private val volumeDialogLogger: VolumeDialogLogger, private val visibilityInteractor: VolumeDialogVisibilityInteractor, configurationController: ConfigurationController, + private val systemClock: SystemClock, ) { private val drawerState = MutableStateFlow<RingerDrawerState>(RingerDrawerState.Initial) @@ -108,6 +111,7 @@ constructor( .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) .build() + private var lastClickTime = 0L init { ringerViewModel .onEach { viewModelState -> @@ -124,6 +128,9 @@ constructor( } fun onRingerButtonClicked(ringerMode: RingerMode, isSelectedButton: Boolean = false) { + val currentTime = systemClock.currentTimeMillis() + if (currentTime - lastClickTime < DRAWER_STATE_ANIMATION_DURATION) return + lastClickTime = currentTime if (drawerState.value is RingerDrawerState.Open && !isSelectedButton) { Events.writeEvent(Events.EVENT_RINGER_TOGGLE, ringerMode.value) volumeDialogLogger.onRingerModeChanged(ringerMode) diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt index 9cf02f26c9f7..ef147c741bec 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt @@ -21,6 +21,7 @@ import android.content.Context import android.graphics.drawable.Drawable import android.media.AudioManager import androidx.annotation.DrawableRes +import com.android.settingslib.R as SettingsR import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.RingerMode @@ -30,8 +31,10 @@ import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf +@SuppressLint("UseCompatLoadingForDrawables") class VolumeDialogSliderIconProvider @Inject constructor( @@ -40,7 +43,30 @@ constructor( private val audioVolumeInteractor: AudioVolumeInteractor, ) { - @SuppressLint("UseCompatLoadingForDrawables") + fun getAudioSharingIcon(isMuted: Boolean): Flow<Drawable> { + return flow { + val iconRes = + if (isMuted) { + R.drawable.ic_volume_media_bt_mute + } else { + R.drawable.ic_volume_media_bt + } + emit(context.getDrawable(iconRes)!!) + } + } + + fun getCastIcon(isMuted: Boolean): Flow<Drawable> { + return flow { + val iconRes = + if (isMuted) { + SettingsR.drawable.ic_volume_remote_mute + } else { + SettingsR.drawable.ic_volume_remote + } + emit(context.getDrawable(iconRes)!!) + } + } + fun getStreamIcon( stream: Int, level: Int, diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt index 89dd0352afa7..a752f1f78e74 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt @@ -57,12 +57,12 @@ private const val VOLUME_UPDATE_GRACE_PERIOD = 1000 class VolumeDialogSliderViewModel @Inject constructor( + private val sliderType: VolumeDialogSliderType, private val interactor: VolumeDialogSliderInteractor, private val visibilityInteractor: VolumeDialogVisibilityInteractor, @VolumeDialog private val coroutineScope: CoroutineScope, private val volumeDialogSliderIconProvider: VolumeDialogSliderIconProvider, private val systemClock: SystemClock, - private val sliderType: VolumeDialogSliderType, private val logger: VolumeDialogLogger, ) { @@ -82,14 +82,24 @@ constructor( model .flatMapLatest { streamModel -> with(streamModel) { - volumeDialogSliderIconProvider.getStreamIcon( - stream = stream, - level = level, - levelMin = levelMin, - levelMax = levelMax, - isMuted = muteSupported && muted, - isRoutedToBluetooth = routedToBluetooth, - ) + val isMuted = muteSupported && muted + when (sliderType) { + is VolumeDialogSliderType.Stream -> + volumeDialogSliderIconProvider.getStreamIcon( + stream = sliderType.audioStream, + level = level, + levelMin = levelMin, + levelMax = levelMax, + isMuted = isMuted, + isRoutedToBluetooth = routedToBluetooth, + ) + is VolumeDialogSliderType.RemoteMediaStream -> { + volumeDialogSliderIconProvider.getCastIcon(isMuted) + } + is VolumeDialogSliderType.AudioSharingStream -> { + volumeDialogSliderIconProvider.getAudioSharingIcon(isMuted) + } + } } .map { icon -> streamModel.toStateModel(icon) } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt index 7da041e7ef19..411288ff1274 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/domain/interactor/AudioSharingInteractor.kt @@ -22,6 +22,7 @@ import android.media.AudioManager.STREAM_MUSIC import androidx.annotation.IntRange import com.android.app.tracing.coroutines.launchTraced as launch import com.android.settingslib.bluetooth.BluetoothUtils +import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.flags.Flags import com.android.settingslib.volume.data.repository.AudioSharingRepository import com.android.settingslib.volume.data.repository.AudioSharingRepository.Companion.AUDIO_SHARING_VOLUME_MAX @@ -42,12 +43,19 @@ import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext interface AudioSharingInteractor { /** Audio sharing state on the device. */ val isInAudioSharing: Flow<Boolean> + /** Primary audio sharing device. */ + val primaryDevice: Flow<CachedBluetoothDevice?> + + /** Secondary audio sharing device. */ + val secondaryDevice: Flow<CachedBluetoothDevice?> + /** Audio sharing secondary headset volume changes. */ val volume: Flow<Int?> @@ -86,6 +94,11 @@ constructor( private val audioSharingRepository: AudioSharingRepository, ) : AudioSharingInteractor { override val isInAudioSharing: Flow<Boolean> = audioSharingRepository.inAudioSharing + override val primaryDevice: Flow<CachedBluetoothDevice?> + get() = audioSharingRepository.primaryDevice + + override val secondaryDevice: Flow<CachedBluetoothDevice?> + get() = audioSharingRepository.secondaryDevice override val volume: Flow<Int?> = combine(audioSharingRepository.secondaryGroupId, audioSharingRepository.volumeMap) { @@ -148,6 +161,8 @@ constructor( @SysUISingleton class AudioSharingInteractorEmptyImpl @Inject constructor() : AudioSharingInteractor { override val isInAudioSharing: Flow<Boolean> = flowOf(false) + override val primaryDevice: Flow<CachedBluetoothDevice?> = flowOf(null) + override val secondaryDevice: Flow<CachedBluetoothDevice?> = flowOf(null) override val volume: Flow<Int?> = emptyFlow() override val volumeMin: Int = EMPTY_VOLUME override val volumeMax: Int = EMPTY_VOLUME diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt index 1e4afc0ac5fe..a326da45a7fc 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt @@ -21,6 +21,7 @@ import com.android.settingslib.volume.data.repository.AudioSystemRepository import com.android.settingslib.volume.domain.interactor.AudioModeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.Flags +import com.android.systemui.volume.domain.interactor.AudioSharingInteractor import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession import com.android.systemui.volume.panel.component.mediaoutput.shared.model.isTheSameSession @@ -44,6 +45,7 @@ constructor( mediaOutputInteractor: MediaOutputInteractor, audioModeInteractor: AudioModeInteractor, private val audioSystemRepository: AudioSystemRepository, + audioSharingInteractor: AudioSharingInteractor, ) { val volumePanelSliders: StateFlow<List<SliderType>> = @@ -51,7 +53,8 @@ constructor( mediaOutputInteractor.activeMediaDeviceSessions, mediaOutputInteractor.defaultActiveMediaSession.filterData(), audioModeInteractor.isOngoingCall, - ) { activeSessions, defaultSession, isOngoingCall -> + audioSharingInteractor.volume, + ) { activeSessions, defaultSession, isOngoingCall, audioSharingVolume -> coroutineScope { val viewModels = buildList { if (isOngoingCall) { @@ -61,8 +64,14 @@ constructor( if (defaultSession?.isTheSameSession(activeSessions.remote) == true) { addSession(activeSessions.remote) addStream(AudioManager.STREAM_MUSIC) + if (Flags.showAudioSharingSliderInVolumePanel()) { + audioSharingVolume?.let { addAudioSharingStream() } + } } else { addStream(AudioManager.STREAM_MUSIC) + if (Flags.showAudioSharingSliderInVolumePanel()) { + audioSharingVolume?.let { addAudioSharingStream() } + } addSession(activeSessions.remote) } @@ -89,13 +98,18 @@ constructor( // Hide other streams except STREAM_MUSIC if the isSingleVolume mode is on. This makes sure // the volume slider in volume panel is consistent with the volume slider inside system // settings app. - if (Flags.onlyShowMediaStreamSliderInSingleVolumeMode() && - audioSystemRepository.isSingleVolume && - stream != AudioManager.STREAM_MUSIC + if ( + Flags.onlyShowMediaStreamSliderInSingleVolumeMode() && + audioSystemRepository.isSingleVolume && + stream != AudioManager.STREAM_MUSIC ) { return } add(SliderType.Stream(AudioStream(stream))) } + + private fun MutableList<SliderType>.addAudioSharingStream() { + add(SliderType.AudioSharingStream) + } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/model/SliderType.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/model/SliderType.kt index 6129ce543e2e..f180744eac22 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/model/SliderType.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/model/SliderType.kt @@ -27,4 +27,7 @@ sealed interface SliderType { /** The represents media device casting volume. */ data class MediaDeviceCast(val session: MediaDeviceSession) : SliderType + + /** Represents the audio sharing volume stream. */ + data object AudioSharingStream : SliderType } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt new file mode 100644 index 000000000000..4ce9fe561aed --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt @@ -0,0 +1,130 @@ +/* + * 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.Context +import com.android.internal.logging.UiEventLogger +import com.android.systemui.Flags +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel +import com.android.systemui.res.R +import com.android.systemui.volume.domain.interactor.AudioSharingInteractor +import com.android.systemui.volume.panel.ui.VolumePanelUiEvent +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import kotlin.math.roundToInt +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn + +@OptIn(ExperimentalCoroutinesApi::class) +class AudioSharingStreamSliderViewModel +@AssistedInject +constructor( + @Assisted private val coroutineScope: CoroutineScope, + private val context: Context, + private val audioSharingInteractor: AudioSharingInteractor, + private val uiEventLogger: UiEventLogger, + private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, +) : SliderViewModel { + private val volumeChanges = MutableStateFlow<Int?>(null) + + override val slider: StateFlow<SliderState> = + combine(audioSharingInteractor.volume, audioSharingInteractor.secondaryDevice) { + volume, + device -> + val deviceName = device?.name ?: return@combine SliderState.Empty + if (volume == null) { + SliderState.Empty + } else { + State( + value = volume.toFloat(), + valueRange = + audioSharingInteractor.volumeMin.toFloat()..audioSharingInteractor + .volumeMax + .toFloat(), + icon = Icon.Resource(R.drawable.ic_volume_media_bt, null), + label = deviceName, + ) + } + } + .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty) + + init { + volumeChanges + .filterNotNull() + .onEach { audioSharingInteractor.setStreamVolume(it) } + .launchIn(coroutineScope) + } + + override fun onValueChanged(state: SliderState, newValue: Float) { + val audioViewModel = state as? State + audioViewModel ?: return + volumeChanges.tryEmit(newValue.roundToInt()) + } + + override fun onValueChangeFinished() { + uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_AUDIO_SHARING_SLIDER_TOUCHED) + } + + override fun toggleMuted(state: SliderState) {} + + override fun getSliderHapticsViewModelFactory(): SliderHapticsViewModel.Factory? = + if (Flags.hapticsForComposeSliders() && slider.value != SliderState.Empty) { + hapticsViewModelFactory + } else { + null + } + + private data class State( + override val value: Float, + override val valueRange: ClosedFloatingPointRange<Float>, + override val icon: Icon, + override val label: String, + ) : SliderState { + override val isEnabled: Boolean + get() = true + + override val a11yStep: Int + get() = 1 + + override val disabledMessage: String? + get() = null + + override val isMutable: Boolean + get() = false + + override val a11yClickDescription: String? + get() = null + + override val a11yStateDescription: String? + get() = null + } + + @AssistedFactory + interface Factory { + fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel + } +} diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt index 328d1245e4a5..4410cb156723 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt @@ -21,6 +21,7 @@ import android.media.AudioManager import android.util.Log import com.android.app.tracing.coroutines.launchTraced as launch import com.android.internal.logging.UiEventLogger +import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.settingslib.volume.shared.model.AudioStreamModel @@ -31,6 +32,8 @@ import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel import com.android.systemui.modes.shared.ModesUiIcons import com.android.systemui.res.R import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor +import com.android.systemui.util.kotlin.combine +import com.android.systemui.volume.domain.interactor.AudioSharingInteractor import com.android.systemui.volume.panel.shared.VolumePanelLogger import com.android.systemui.volume.panel.ui.VolumePanelUiEvent import dagger.assisted.Assisted @@ -42,7 +45,6 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn @@ -59,6 +61,7 @@ constructor( private val context: Context, private val audioVolumeInteractor: AudioVolumeInteractor, private val zenModeInteractor: ZenModeInteractor, + private val audioSharingInteractor: AudioSharingInteractor, private val uiEventLogger: UiEventLogger, private val volumePanelLogger: VolumePanelLogger, private val hapticsViewModelFactory: SliderHapticsViewModel.Factory, @@ -66,14 +69,6 @@ constructor( private val volumeChanges = MutableStateFlow<Int?>(null) private val audioStream = audioStreamWrapper.audioStream - private val iconsByStream = - mapOf( - AudioStream(AudioManager.STREAM_MUSIC) to R.drawable.ic_music_note, - AudioStream(AudioManager.STREAM_VOICE_CALL) to R.drawable.ic_call, - AudioStream(AudioManager.STREAM_RING) to R.drawable.ic_ring_volume, - AudioStream(AudioManager.STREAM_NOTIFICATION) to R.drawable.ic_volume_ringer, - AudioStream(AudioManager.STREAM_ALARM) to R.drawable.ic_volume_alarm, - ) private val labelsByStream = mapOf( AudioStream(AudioManager.STREAM_MUSIC) to R.string.stream_music, @@ -102,9 +97,18 @@ constructor( audioVolumeInteractor.canChangeVolume(audioStream), audioVolumeInteractor.ringerMode, streamDisabledMessage(), - ) { model, isEnabled, ringerMode, streamDisabledMessage -> + audioSharingInteractor.isInAudioSharing, + audioSharingInteractor.primaryDevice, + ) { model, isEnabled, ringerMode, streamDisabledMessage, isInAudioSharing, primaryDevice + -> volumePanelLogger.onVolumeUpdateReceived(audioStream, model.volume) - model.toState(isEnabled, ringerMode, streamDisabledMessage) + model.toState( + isEnabled, + ringerMode, + streamDisabledMessage, + isInAudioSharing, + primaryDevice, + ) } .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty) @@ -147,14 +151,15 @@ constructor( isEnabled: Boolean, ringerMode: RingerMode, disabledMessage: String?, + inAudioSharing: Boolean, + primaryDevice: CachedBluetoothDevice?, ): State { - val label = - labelsByStream[audioStream]?.let(context::getString) - ?: error("No label for the stream: $audioStream") + val label = getLabel(inAudioSharing, primaryDevice) + val icon = getIcon(ringerMode, inAudioSharing) return State( value = volume.toFloat(), valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(), - icon = getIcon(ringerMode), + icon = icon, label = label, disabledMessage = disabledMessage, isEnabled = isEnabled, @@ -222,7 +227,22 @@ constructor( } } - private fun AudioStreamModel.getIcon(ringerMode: RingerMode): Icon { + private fun AudioStreamModel.getLabel( + inAudioSharing: Boolean, + primaryDevice: CachedBluetoothDevice?, + ): String = + if ( + Flags.showAudioSharingSliderInVolumePanel() && + audioStream.value == AudioManager.STREAM_MUSIC && + inAudioSharing + ) { + primaryDevice?.name ?: context.getString(R.string.stream_music) + } else { + labelsByStream[audioStream]?.let(context::getString) + ?: error("No label for the stream: $audioStream") + } + + private fun AudioStreamModel.getIcon(ringerMode: RingerMode, inAudioSharing: Boolean): Icon { val iconRes = if (isMuted) { if (isAffectedByRingerMode) { @@ -232,18 +252,36 @@ constructor( R.drawable.ic_volume_off } } else { - R.drawable.ic_volume_off + if ( + Flags.showAudioSharingSliderInVolumePanel() && + audioStream.value == AudioManager.STREAM_MUSIC && + inAudioSharing + ) { + R.drawable.ic_volume_media_bt_mute + } else R.drawable.ic_volume_off } } else { - iconsByStream[audioStream] - ?: run { - Log.wtf(TAG, "No icon for the stream: $audioStream") - R.drawable.ic_music_note - } + getIconByStream(audioStream, inAudioSharing) } return Icon.Resource(iconRes, null) } + private fun getIconByStream(audioStream: AudioStream, inAudioSharing: Boolean): Int = + when (audioStream.value) { + AudioManager.STREAM_MUSIC -> + if (Flags.showAudioSharingSliderInVolumePanel() && inAudioSharing) { + R.drawable.ic_volume_media_bt + } else R.drawable.ic_music_note + AudioManager.STREAM_VOICE_CALL -> R.drawable.ic_call + AudioManager.STREAM_RING -> R.drawable.ic_ring_volume + AudioManager.STREAM_NOTIFICATION -> R.drawable.ic_volume_ringer + AudioManager.STREAM_ALARM -> R.drawable.ic_volume_alarm + else -> { + Log.wtf(TAG, "No icon for the stream: $audioStream") + R.drawable.ic_music_note + } + } + private val AudioStreamModel.volumeRange: IntRange get() = minVolume..maxVolume 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 96afbc1feaaf..28f11050fa4a 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 @@ -16,6 +16,7 @@ package com.android.systemui.volume.panel.component.volume.ui.viewmodel +import com.android.app.tracing.coroutines.launchTraced as launch import com.android.settingslib.volume.domain.interactor.AudioModeInteractor import com.android.settingslib.volume.shared.model.AudioStream import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor @@ -23,6 +24,7 @@ import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession import com.android.systemui.volume.panel.component.volume.domain.interactor.AudioSlidersInteractor import com.android.systemui.volume.panel.component.volume.domain.model.SliderType +import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioSharingStreamSliderViewModel import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioStreamSliderViewModel import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.CastVolumeSliderViewModel import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel @@ -45,7 +47,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.transformLatest -import com.android.app.tracing.coroutines.launchTraced as launch /** * Controls the behaviour of the whole audio @@ -61,6 +62,7 @@ constructor( mediaDeviceSessionInteractor: MediaDeviceSessionInteractor, private val streamSliderViewModelFactory: AudioStreamSliderViewModel.Factory, private val castVolumeSliderViewModelFactory: CastVolumeSliderViewModel.Factory, + private val audioSharingStreamSliderViewModelFactory: AudioSharingStreamSliderViewModel.Factory, audioModeInteractor: AudioModeInteractor, streamsInteractor: AudioSlidersInteractor, ) { @@ -108,6 +110,7 @@ constructor( is SliderType.Stream -> createStreamViewModel(type.stream) is SliderType.MediaDeviceCast -> createSessionViewModel(type.session) + is SliderType.AudioSharingStream -> createAudioSharingViewModel() } } emit(viewModels) @@ -138,11 +141,15 @@ constructor( } private fun CoroutineScope.createStreamViewModel( - stream: AudioStream, + stream: AudioStream ): AudioStreamSliderViewModel { return streamSliderViewModelFactory.create( AudioStreamSliderViewModel.FactoryAudioStreamWrapper(stream), this, ) } + + private fun CoroutineScope.createAudioSharingViewModel(): AudioSharingStreamSliderViewModel { + return audioSharingStreamSliderViewModelFactory.create(this) + } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt index 8b8714fcca8c..d3a4fe86e827 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt +++ b/packages/SystemUI/src/com/android/systemui/volume/panel/ui/VolumePanelUiEvent.kt @@ -34,6 +34,8 @@ enum class VolumePanelUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum { @UiEvent(doc = "The notification volume slider is touched") VOLUME_PANEL_NOTIFICATION_SLIDER_TOUCHED(1642), @UiEvent(doc = "The alarm volume slider is touched") VOLUME_PANEL_ALARM_SLIDER_TOUCHED(1643), + @UiEvent(doc = "The audio sharing volume slider is touched") + VOLUME_PANEL_AUDIO_SHARING_SLIDER_TOUCHED(2068), @UiEvent(doc = "Live caption toggle is shown") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_SHOWN(1644), @UiEvent(doc = "Live caption toggle is gone") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_GONE(1645), @UiEvent(doc = "Live caption toggle is clicked") VOLUME_PANEL_LIVE_CAPTION_TOGGLE_CLICKED(1646), diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt index 2491ca7565c7..d2069cfdfdc6 100644 --- a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt @@ -19,12 +19,12 @@ package com.android.systemui.window.ui import android.util.Log import android.view.Choreographer import android.view.Choreographer.FrameCallback +import com.android.systemui.Flags import com.android.systemui.lifecycle.WindowLifecycleState import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.lifecycle.viewModel import com.android.systemui.scene.ui.view.WindowRootView import com.android.systemui.statusbar.BlurUtils -import com.android.systemui.window.flag.WindowBlurFlag import com.android.systemui.window.ui.viewmodel.WindowRootViewModel import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.filter @@ -43,7 +43,7 @@ object WindowRootViewBinder { blurUtils: BlurUtils?, choreographer: Choreographer?, ) { - if (!WindowBlurFlag.isEnabled) return + if (!Flags.bouncerUiRevamp()) return if (blurUtils == null || choreographer == null) return view.repeatWhenAttached { diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt index 0508c2cf0426..072caa74df20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaHierarchyManagerTest.kt @@ -31,6 +31,7 @@ import com.android.systemui.communal.shared.model.CommunalScenes import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq import com.android.systemui.dreams.DreamOverlayStateController +import com.android.systemui.dump.DumpManager import com.android.systemui.flags.DisableSceneContainer import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository @@ -110,6 +111,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { @Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController @Mock private lateinit var shadeInteractor: ShadeInteractor @Mock lateinit var logger: MediaViewLogger + @Mock lateinit var dumpManager: DumpManager @Captor private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)> @Captor @@ -166,6 +168,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { testScope.backgroundScope, ResourcesSplitShadeStateController(), logger, + dumpManager, ) verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture()) verify(statusBarStateController).addCallback(statusBarCallback.capture()) @@ -209,7 +212,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) val observer = wakefullnessObserver.value assertNotNull("lifecycle observer wasn't registered", observer) @@ -222,7 +225,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) } @@ -236,7 +239,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) val observer = wakefullnessObserver.value assertNotNull("lifecycle observer wasn't registered", observer) @@ -249,7 +252,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) } @@ -263,7 +266,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) configurationController.notifyConfigurationChanged() @@ -273,7 +276,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) } @@ -287,7 +290,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) val observer = wakefullnessObserver.value assertNotNull("lifecycle observer wasn't registered", observer) @@ -299,7 +302,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), anyBoolean(), anyLong(), - anyLong() + anyLong(), ) } @@ -315,7 +318,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) @@ -327,7 +330,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) // Let's make sure alpha is set @@ -528,7 +531,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) @@ -539,7 +542,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) } @@ -559,7 +562,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) @@ -576,7 +579,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) } @@ -597,7 +600,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) val captor = ArgumentCaptor.forClass(Boolean::class.java) @@ -630,7 +633,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) val captor = ArgumentCaptor.forClass(Boolean::class.java) @@ -666,7 +669,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) } @@ -689,7 +692,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { nullable(), eq(false), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) @@ -704,7 +707,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) } @@ -734,7 +737,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { anyOrNull(), eq(false), anyLong(), - anyLong() + anyLong(), ) clearInvocations(mediaCarouselController) @@ -749,7 +752,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { any<MediaHostState>(), eq(false), anyLong(), - anyLong() + anyLong(), ) } @@ -788,7 +791,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED) statusBarCallback.value.onStatePreChange( StatusBarState.KEYGUARD, - StatusBarState.SHADE_LOCKED + StatusBarState.SHADE_LOCKED, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java index a17f100904be..e5376d26840d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java @@ -88,8 +88,13 @@ public class RecordingControllerTest extends SysuiTestCase { private ScreenRecordPermissionDialogDelegate.Factory mScreenRecordPermissionDialogDelegateFactory; @Mock + private ScreenRecordPermissionViewBinder.Factory + mScreenRecordPermissionViewBinderFactory; + @Mock private ScreenRecordPermissionDialogDelegate mScreenRecordPermissionDialogDelegate; @Mock + private ScreenRecordPermissionViewBinder mScreenRecordPermissionViewBinder; + @Mock private SystemUIDialog mScreenRecordSystemUIDialog; private RecordingController mController; @@ -106,6 +111,8 @@ public class RecordingControllerTest extends SysuiTestCase { .thenReturn(mScreenCaptureDisabledDialog); when(mScreenRecordPermissionDialogDelegateFactory.create(any(), any(), anyInt(), any())) .thenReturn(mScreenRecordPermissionDialogDelegate); + when(mScreenRecordPermissionViewBinderFactory.create(any(), anyInt(), any(), any())) + .thenReturn(mScreenRecordPermissionViewBinder); when(mScreenRecordPermissionDialogDelegate.createDialog()) .thenReturn(mScreenRecordSystemUIDialog); mController = new RecordingController( @@ -116,7 +123,8 @@ public class RecordingControllerTest extends SysuiTestCase { new RecordingControllerLogger(logcatLogBuffer("RecordingControllerTest")), mMediaProjectionMetricsLogger, mScreenCaptureDisabledDialogDelegate, - mScreenRecordPermissionDialogDelegateFactory + mScreenRecordPermissionDialogDelegateFactory, + mScreenRecordPermissionViewBinderFactory ); mController.addCallback(mCallback); } @@ -238,6 +246,26 @@ public class RecordingControllerTest extends SysuiTestCase { } @Test + public void testCreateScreenRecordPermissionViewBinder() { + ScreenRecordPermissionViewBinder viewBinder = + mController.createScreenRecordPermissionViewBinder( + /* onStartRecordingClicked= */ null); + assertThat(viewBinder).isEqualTo(mScreenRecordPermissionViewBinder); + } + + @Test + public void testScreenCapturingAllowed_returnsFalseIsScreenCaptureDisabled() { + when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false); + assertFalse(mController.isScreenCaptureDisabled()); + } + + @Test + public void testScreenCapturingNotAllowed_returnsTrueIsScreenCaptureDisabled() { + when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(true); + assertTrue(mController.isScreenCaptureDisabled()); + } + + @Test public void testScreenCapturingAllowed_logsProjectionInitiated() { when(mDevicePolicyResolver.isScreenCaptureCompletelyDisabled((any()))).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 72d1db3affe8..281ce16b539f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -22,6 +22,7 @@ import static android.app.Notification.CATEGORY_EVENT; import static android.app.Notification.CATEGORY_MESSAGE; import static android.app.Notification.CATEGORY_REMINDER; import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED; +import static android.app.Notification.FLAG_PROMOTED_ONGOING; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking; @@ -43,6 +44,8 @@ import android.graphics.drawable.Icon; import android.media.session.MediaSession; import android.os.Bundle; import android.os.UserHandle; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; @@ -54,6 +57,8 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.res.R; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; +import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips; +import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi; import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; @@ -280,6 +285,40 @@ public class NotificationEntryTest extends SysuiTestCase { } @Test + @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME}) + public void isPromotedOngoing_noFlagOnNotif_false() { + mEntry.getSbn().getNotification().flags &= ~FLAG_PROMOTED_ONGOING; + + assertFalse(mEntry.isPromotedOngoing()); + } + + @Test + @DisableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME}) + public void isPromotedOngoing_statusBarNotifChipsFlagAndUiFlagOff_false() { + mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING; + + assertFalse(mEntry.isPromotedOngoing()); + } + + @Test + @EnableFlags(PromotedNotificationUi.FLAG_NAME) + @DisableFlags(StatusBarNotifChips.FLAG_NAME) + public void isPromotedOngoing_uiFlagOnAndNotifHasFlag_true() { + mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING; + + assertTrue(mEntry.isPromotedOngoing()); + } + + @Test + @EnableFlags(StatusBarNotifChips.FLAG_NAME) + @DisableFlags(PromotedNotificationUi.FLAG_NAME) + public void isPromotedOngoing_statusBarNotifChipsFlagOnAndNotifHasFlag_true() { + mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING; + + assertTrue(mEntry.isPromotedOngoing()); + } + + @Test public void testIsNotificationVisibilityPrivate_true() { assertTrue(mEntry.isNotificationVisibilityPrivate()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java index f9df6c79e140..0d0415e0d72d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java @@ -67,6 +67,7 @@ import com.android.systemui.statusbar.data.repository.StatusBarConfigurationCont import com.android.systemui.statusbar.data.repository.StatusBarConfigurationControllerStore; import com.android.systemui.statusbar.disableflags.DisableFlagsLogger; import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; +import com.android.systemui.statusbar.headsup.shared.StatusBarNoHunBehavior; import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerStatusBarViewBinder; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; @@ -624,13 +625,14 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility()); } - @Test - @DisableFlags({ - StatusBarNotifChips.FLAG_NAME, - StatusBarRootModernization.FLAG_NAME, - StatusBarChipsModernization.FLAG_NAME - }) - public void hasOngoingActivityButAlsoHun_chipHidden_notifsFlagOff() { + @Test + @DisableFlags({ + StatusBarNotifChips.FLAG_NAME, + StatusBarRootModernization.FLAG_NAME, + StatusBarChipsModernization.FLAG_NAME, + StatusBarNoHunBehavior.FLAG_NAME, + }) + public void hasOngoingActivityButAlsoHun_chipHidden_notifChipsFlagOff() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged( @@ -646,8 +648,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { @Test @EnableFlags({StatusBarNotifChips.FLAG_NAME}) - @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME}) - public void hasOngoingActivitiesButAlsoHun_chipsHidden_notifsFlagOn() { + @DisableFlags({ + StatusBarRootModernization.FLAG_NAME, + StatusBarChipsModernization.FLAG_NAME, + StatusBarNoHunBehavior.FLAG_NAME + }) + public void hasOngoingActivitiesButAlsoHun_chipsHidden_notifChipsFlagOn() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged( @@ -662,13 +668,31 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { assertEquals(View.GONE, getSecondaryOngoingActivityChipView().getVisibility()); } + @Test + @EnableFlags({StatusBarNotifChips.FLAG_NAME, StatusBarNoHunBehavior.FLAG_NAME}) + @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME}) + public void hasOngoingActivitiesButAlsoHun_noHunBehaviorFlagOn_chipsNotHidden() { + CollapsedStatusBarFragment fragment = resumeAndGetFragment(); + + mCollapsedStatusBarViewBinder.getListener().onOngoingActivityStatusChanged( + /* hasPrimaryOngoingActivity= */ true, + /* hasSecondaryOngoingActivity= */ true, + /* shouldAnimate= */ false); + when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true); + + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + assertEquals(View.VISIBLE, getPrimaryOngoingActivityChipView().getVisibility()); + assertEquals(View.VISIBLE, getSecondaryOngoingActivityChipView().getVisibility()); + } + @Test @DisableFlags({ StatusBarNotifChips.FLAG_NAME, StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME }) - public void primaryOngoingActivityEnded_chipHidden_notifsFlagOff() { + public void primaryOngoingActivityEnded_chipHidden_notifChipsFlagOff() { resumeAndGetFragment(); // Ongoing activity started @@ -948,9 +972,13 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { assertEquals(View.VISIBLE, getClockView().getVisibility()); } - @Test - @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME}) - public void disable_shouldHeadsUpStatusBarBeVisibleTrue_clockDisabled() { + @Test + @DisableFlags({ + StatusBarRootModernization.FLAG_NAME, + StatusBarChipsModernization.FLAG_NAME, + StatusBarNoHunBehavior.FLAG_NAME, + }) + public void disable_shouldHeadsUpStatusBarBeVisibleTrue_clockDisabled() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true); @@ -960,7 +988,11 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { } @Test - @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME}) + @DisableFlags({ + StatusBarRootModernization.FLAG_NAME, + StatusBarChipsModernization.FLAG_NAME, + StatusBarNoHunBehavior.FLAG_NAME, + }) public void disable_shouldHeadsUpStatusBarBeVisibleFalse_clockNotDisabled() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(false); @@ -971,6 +1003,18 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest { } @Test + @DisableFlags({StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME}) + @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME) + public void disable_shouldHeadsUpStatusBarBeVisibleTrue_butNoHunBehaviorOn_clockNotDisabled() { + CollapsedStatusBarFragment fragment = resumeAndGetFragment(); + when(mHeadsUpAppearanceController.shouldHeadsUpStatusBarBeVisible()).thenReturn(true); + + fragment.disable(DEFAULT_DISPLAY, 0, 0, false); + + assertEquals(View.VISIBLE, getClockView().getVisibility()); + } + + @Test public void setUp_fragmentCreatesDaggerComponent() { CollapsedStatusBarFragment fragment = resumeAndGetFragment(); diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothManagerKosmos.kt index eef89e7dac68..3d58cf58d7b9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothManagerKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothManagerKosmos.kt @@ -18,10 +18,12 @@ package com.android.systemui.bluetooth import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.kosmos.Kosmos -import com.android.systemui.util.mockito.mock -import com.android.systemui.util.mockito.whenever +import org.mockito.kotlin.mock var Kosmos.localBluetoothManager: LocalBluetoothManager? by Kosmos.Fixture { - mock { whenever(cachedDeviceManager).thenReturn(cachedBluetoothDeviceManager) } + mock { + on { cachedDeviceManager }.thenReturn(cachedBluetoothDeviceManager) + on { profileManager }.thenReturn(localBluetoothProfileManager) + } } diff --git a/packages/SystemUI/src/com/android/systemui/window/flag/WindowBlurFlag.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothProfileManagerKosmos.kt index 8b6c8601f5d2..34d7848a70aa 100644 --- a/packages/SystemUI/src/com/android/systemui/window/flag/WindowBlurFlag.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bluetooth/LocalBluetoothProfileManagerKosmos.kt @@ -14,19 +14,10 @@ * limitations under the License. */ -package com.android.systemui.window.flag +package com.android.systemui.bluetooth -import com.android.systemui.Flags +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.util.mockito.mock -/** - * Flag that controls whether the background surface is blurred or not while on the - * lockscreen/shade/bouncer. This makes the background of scrim, bouncer and few other opaque - * surfaces transparent so that we can see the blur effect on the background surface (wallpaper). - */ -object WindowBlurFlag { - /** Whether the blur is enabled or not */ - @JvmStatic - val isEnabled - // Add flags here that require scrims/background surfaces to be transparent. - get() = Flags.notificationShadeBlur() || Flags.bouncerUiRevamp() -} +var Kosmos.localBluetoothProfileManager: LocalBluetoothProfileManager by Kosmos.Fixture { mock {} } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt index 487049740079..e30e92020706 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt @@ -33,10 +33,7 @@ import kotlinx.coroutines.flow.asStateFlow @SysUISingleton class FakeConfigurationRepository @Inject constructor() : ConfigurationRepository { private val _onAnyConfigurationChange = - MutableSharedFlow<Unit>( - replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST, - ) + MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) override val onAnyConfigurationChange: Flow<Unit> = _onAnyConfigurationChange.asSharedFlow() private val _onConfigurationChange = @@ -53,7 +50,7 @@ class FakeConfigurationRepository @Inject constructor() : ConfigurationRepositor get() = _onMovedToDisplay private val _scaleForResolution = MutableStateFlow(1f) - override val scaleForResolution: Flow<Float> = _scaleForResolution.asStateFlow() + override val scaleForResolution: StateFlow<Float> = _scaleForResolution.asStateFlow() private val pixelSizes = mutableMapOf<Int, MutableStateFlow<Int>>() diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt index 9a6f2f60aac8..4667bf5292fa 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/education/data/repository/FakeContextualEducationRepository.kt @@ -96,7 +96,7 @@ class FakeContextualEducationRepository : ContextualEducationRepository { override suspend fun updateGestureEduModel( gestureType: GestureType, - transform: (GestureEduModel) -> GestureEduModel, + transform: (GestureEduModel) -> GestureEduModel ) { val gestureModels = when (gestureType) { @@ -117,11 +117,6 @@ class FakeContextualEducationRepository : ContextualEducationRepository { _eduDeviceConnectionTime.value = transform(currentModel) } - override suspend fun clear() { - val currentUserMap = userGestureMap[currentUser]!! - currentUserMap.clear() - } - override val keyboardShortcutTriggered: Flow<GestureType> get() = _keyboardShortcutTriggered.filterNotNull() diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DismissKeyguardInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt index 82a5311269f0..56a7b4db5455 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/DismissKeyguardInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissTransitionInteractor.kt @@ -18,10 +18,12 @@ package com.android.systemui.keyguard.domain.interactor import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope val Kosmos.keyguardDismissTransitionInteractor: KeyguardDismissTransitionInteractor by Kosmos.Fixture { KeyguardDismissTransitionInteractor( + scope = testScope, repository = keyguardTransitionRepository, fromLockscreenTransitionInteractor = fromLockscreenTransitionInteractor, fromPrimaryBouncerTransitionInteractor = fromPrimaryBouncerTransitionInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt index 3c37101cfe66..13cbddff8803 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt @@ -20,6 +20,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor import com.android.systemui.statusbar.policy.ui.dialog.modesDialogDelegate +import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger import javax.inject.Provider val Kosmos.modesTileUserActionInteractor: ModesTileUserActionInteractor by @@ -28,5 +29,6 @@ val Kosmos.modesTileUserActionInteractor: ModesTileUserActionInteractor by qsTileIntentUserInputHandler, Provider { modesDialogDelegate }.get(), zenModeInteractor, + modesDialogEventLogger, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelKosmos.kt index 01cac4c1e030..99323dbd7cce 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelKosmos.kt @@ -31,3 +31,8 @@ val Kosmos.footerViewModel by Fixture { shadeInteractor = shadeInteractor, ) } +val Kosmos.footerViewModelFactory: FooterViewModel.Factory by Fixture { + object : FooterViewModel.Factory { + override fun create() = footerViewModel + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt index c3bc744e09b0..fbc2a21b0888 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelKosmos.kt @@ -24,7 +24,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.statusbar.domain.interactor.remoteInputInteractor import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor import com.android.systemui.statusbar.notification.emptyshade.ui.viewmodel.emptyShadeViewModelFactory -import com.android.systemui.statusbar.notification.footer.ui.viewmodel.footerViewModel +import com.android.systemui.statusbar.notification.footer.ui.viewmodel.footerViewModelFactory import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.notificationShelfViewModel import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackInteractor @@ -35,7 +35,7 @@ val Kosmos.notificationListViewModel by Fixture { NotificationListViewModel( notificationShelfViewModel, hideListViewModel, - Optional.of(footerViewModel), + footerViewModelFactory, emptyShadeViewModelFactory, Optional.of(notificationListLoggerViewModel), activeNotificationsInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt index 766b280334c8..f4e74fe0e6bb 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModelBuilder.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone.ongoingcall.shared.model import android.app.PendingIntent import com.android.systemui.statusbar.StatusBarIconView +import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel /** Helper for building [OngoingCallModel.InCall] instances in tests. */ fun inCallModel( @@ -25,4 +26,5 @@ fun inCallModel( notificationIcon: StatusBarIconView? = null, intent: PendingIntent? = null, notificationKey: String = "test", -) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent, notificationKey) + promotedContent: PromotedNotificationContentModel? = null, +) = OngoingCallModel.InCall(startTimeMs, notificationIcon, intent, notificationKey, promotedContent) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt index db7e31bb2cb6..f8bf3c3fbbd9 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelKosmos.kt @@ -21,6 +21,7 @@ import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope +import com.android.systemui.log.table.tableLogBufferFactory import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor import com.android.systemui.scene.domain.interactor.sceneInteractor import com.android.systemui.shade.domain.interactor.shadeInteractor @@ -39,6 +40,7 @@ var Kosmos.homeStatusBarViewModel: HomeStatusBarViewModel by Kosmos.Fixture { HomeStatusBarViewModelImpl( testableContext.displayId, + tableLogBufferFactory, homeStatusBarInteractor, homeStatusBarIconBlockListInteractor, lightsOutInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt index 6c98d19db5d7..ef043e0177a5 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/ui/dialog/ModesDialogDelegateKosmos.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy.ui.dialog +import android.content.mockedContext import com.android.systemui.animation.dialogTransitionAnimator import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.mainCoroutineContext @@ -30,6 +31,7 @@ val Kosmos.mockModesDialogDelegate by Kosmos.Fixture { mock<ModesDialogDelegate> var Kosmos.modesDialogDelegate: ModesDialogDelegate by Kosmos.Fixture { ModesDialogDelegate( + mockedContext, systemUIDialogFactory, dialogTransitionAnimator, activityStarter, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt index 5da6ee95234c..6e76cf34c652 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt @@ -16,6 +16,7 @@ package com.android.systemui.volume.data.repository +import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.volume.data.repository.AudioSharingRepository import com.android.settingslib.volume.data.repository.GroupIdToVolumes import kotlinx.coroutines.flow.MutableStateFlow @@ -28,11 +29,17 @@ class FakeAudioSharingRepository : AudioSharingRepository { MutableStateFlow(TEST_GROUP_ID_INVALID) private val mutableSecondaryGroupId: MutableStateFlow<Int> = MutableStateFlow(TEST_GROUP_ID_INVALID) + private val mutablePrimaryDevice: MutableStateFlow<CachedBluetoothDevice?> = + MutableStateFlow(null) + private val mutableSecondaryDevice: MutableStateFlow<CachedBluetoothDevice?> = + MutableStateFlow(null) private val mutableVolumeMap: MutableStateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap()) override val inAudioSharing: StateFlow<Boolean> = mutableInAudioSharing override val primaryGroupId: StateFlow<Int> = mutablePrimaryGroupId override val secondaryGroupId: StateFlow<Int> = mutableSecondaryGroupId + override val primaryDevice: StateFlow<CachedBluetoothDevice?> = mutablePrimaryDevice + override val secondaryDevice: StateFlow<CachedBluetoothDevice?> = mutableSecondaryDevice override val volumeMap: StateFlow<GroupIdToVolumes> = mutableVolumeMap override suspend fun audioSharingAvailable(): Boolean = mutableAvailable @@ -55,6 +62,14 @@ class FakeAudioSharingRepository : AudioSharingRepository { mutableSecondaryGroupId.value = groupId } + fun setPrimaryDevice(device: CachedBluetoothDevice?) { + mutablePrimaryDevice.value = device + } + + fun setSecondaryDevice(device: CachedBluetoothDevice?) { + mutableSecondaryDevice.value = device + } + fun setVolumeMap(volumeMap: GroupIdToVolumes) { mutableVolumeMap.value = volumeMap } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt index 4fda95bab2ec..9f3150f7366a 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/ringer/ui/viewmodel/VolumeDialogRingerDrawerViewModelKosmos.kt @@ -23,6 +23,8 @@ import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testDispatcher import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyInteractor import com.android.systemui.statusbar.policy.configurationController +import com.android.systemui.util.time.fakeSystemClock +import com.android.systemui.util.time.systemClock import com.android.systemui.volume.dialog.domain.interactor.volumeDialogVisibilityInteractor import com.android.systemui.volume.dialog.ringer.domain.volumeDialogRingerInteractor import com.android.systemui.volume.dialog.shared.volumeDialogLogger @@ -39,5 +41,6 @@ val Kosmos.volumeDialogRingerDrawerViewModel by volumeDialogLogger = volumeDialogLogger, visibilityInteractor = volumeDialogVisibilityInteractor, configurationController = configurationController, + systemClock = fakeSystemClock, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/FakeAudioSharingInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/FakeAudioSharingInteractor.kt index 1fb5e77a3210..78cafbf99f49 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/FakeAudioSharingInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/domain/interactor/FakeAudioSharingInteractor.kt @@ -19,10 +19,11 @@ package com.android.systemui.volume.domain.interactor import android.content.Context import androidx.annotation.IntRange import com.android.dream.lowlight.dagger.qualifiers.Application +import com.android.settingslib.bluetooth.CachedBluetoothDevice import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow -class FakeAudioSharingInteractor : AudioSharingInteractor { +class FakeAudioSharingInteractor() : AudioSharingInteractor { private val mutableInAudioSharing: MutableStateFlow<Boolean> = MutableStateFlow(false) private val mutableVolume: MutableStateFlow<Int?> = MutableStateFlow(null) private var audioSharingVolumeBarAvailable = false @@ -31,6 +32,8 @@ class FakeAudioSharingInteractor : AudioSharingInteractor { override val volume: Flow<Int?> = mutableVolume override val volumeMin: Int = AUDIO_SHARING_VOLUME_MIN override val volumeMax: Int = AUDIO_SHARING_VOLUME_MAX + override val primaryDevice = MutableStateFlow<CachedBluetoothDevice?>(null) + override val secondaryDevice = MutableStateFlow<CachedBluetoothDevice?>(null) override suspend fun audioSharingVolumeBarAvailable(@Application context: Context): Boolean = audioSharingVolumeBarAvailable @@ -54,6 +57,14 @@ class FakeAudioSharingInteractor : AudioSharingInteractor { audioSharingVolumeBarAvailable = available } + fun setPrimaryDevice(device: CachedBluetoothDevice?) { + primaryDevice.value = device + } + + fun setSecondaryDevice(device: CachedBluetoothDevice?) { + secondaryDevice.value = device + } + companion object { const val AUDIO_SHARING_VOLUME_MIN = 0 const val AUDIO_SHARING_VOLUME_MAX = 255 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 index 3bc920edd948..88734cd3b000 100644 --- 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 @@ -20,6 +20,7 @@ import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.volume.data.repository.audioSystemRepository import com.android.systemui.volume.domain.interactor.audioModeInteractor +import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.android.systemui.volume.mediaOutputInteractor val Kosmos.audioSlidersInteractor by @@ -29,5 +30,6 @@ val Kosmos.audioSlidersInteractor by mediaOutputInteractor, audioModeInteractor, audioSystemRepository, + audioSharingInteractor, ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt new file mode 100644 index 000000000000..96bc9722635a --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt @@ -0,0 +1,39 @@ +/* + * 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.haptics.slider.sliderHapticsViewModelFactory +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.volume.domain.interactor.audioSharingInteractor +import kotlinx.coroutines.CoroutineScope + +val Kosmos.audioSharingStreamSliderViewModelFactory by + Kosmos.Fixture { + object : AudioSharingStreamSliderViewModel.Factory { + override fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel { + return AudioSharingStreamSliderViewModel( + coroutineScope, + applicationContext, + audioSharingInteractor, + uiEventLogger, + sliderHapticsViewModelFactory, + ) + } + } + } 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 index a78670d7f1cc..88c716e0ab10 100644 --- 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 @@ -21,6 +21,7 @@ import com.android.internal.logging.uiEventLogger import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory import com.android.systemui.kosmos.Kosmos import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor +import com.android.systemui.volume.domain.interactor.audioSharingInteractor import com.android.systemui.volume.domain.interactor.audioVolumeInteractor import com.android.systemui.volume.shared.volumePanelLogger import kotlinx.coroutines.CoroutineScope @@ -39,6 +40,7 @@ val Kosmos.audioStreamSliderViewModelFactory by applicationContext, audioVolumeInteractor, zenModeInteractor, + audioSharingInteractor, uiEventLogger, volumePanelLogger, sliderHapticsViewModelFactory, 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 index 6e848ce26d9b..a6a4f8368941 100644 --- 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 @@ -22,6 +22,7 @@ import com.android.systemui.volume.domain.interactor.audioModeInteractor 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.audioSharingStreamSliderViewModelFactory import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.audioStreamSliderViewModelFactory import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.castVolumeSliderViewModelFactory @@ -33,6 +34,7 @@ val Kosmos.audioVolumeComponentViewModel by mediaDeviceSessionInteractor, audioStreamSliderViewModelFactory, castVolumeSliderViewModelFactory, + audioSharingStreamSliderViewModelFactory, audioModeInteractor, audioSlidersInteractor, ) diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java index 6467af4355f6..c8c645f1276d 100644 --- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java @@ -138,6 +138,8 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { @NonNull private final Object mCancellationToken = new Object(); @NonNull private final PacketLossCalculator mPacketLossCalculator; + @Nullable private BroadcastReceiver mDeviceIdleReceiver; + @Nullable private IpSecTransformWrapper mInboundTransform; @Nullable private IpSecTransformState mLastIpSecTransformState; @@ -168,19 +170,21 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { // Register for system broadcasts to monitor idle mode change final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); + + mDeviceIdleReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals( + intent.getAction()) + && mPowerManager.isDeviceIdleMode()) { + mLastIpSecTransformState = null; + } + } + }; getVcnContext() .getContext() .registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals( - intent.getAction()) - && mPowerManager.isDeviceIdleMode()) { - mLastIpSecTransformState = null; - } - } - }, + mDeviceIdleReceiver, intentFilter, null /* broadcastPermission not required */, mHandler); @@ -338,7 +342,12 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor { super.close(); if (mInboundTransform != null) { - mInboundTransform.close(); + mInboundTransform = null; + } + + if (mDeviceIdleReceiver != null) { + getVcnContext().getContext().unregisterReceiver(mDeviceIdleReceiver); + mDeviceIdleReceiver = null; } } diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java index 14853440a129..55829a5fe978 100644 --- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java +++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java @@ -165,7 +165,7 @@ public abstract class NetworkMetricMonitor implements AutoCloseable { } } - /** Set the IpSecTransform that applied to the Network being monitored */ + /** Set the IpSecTransform that is applied to the Network being monitored */ public void setInboundTransform(@NonNull IpSecTransform inTransform) { setInboundTransformInternal(new IpSecTransformWrapper(inTransform)); } diff --git a/ravenwood/scripts/pta-framework.sh b/ravenwood/scripts/pta-framework.sh new file mode 100755 index 000000000000..224ab59e2e09 --- /dev/null +++ b/ravenwood/scripts/pta-framework.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# 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. + +# +# Use "ravehleper pta" to create a shell script which: +# - Reads the text "policy" files +# - Convert to java annotations (using sed) +# + +set -e + + +# Uncomment it to always build ravenhelper (slow) +# ${BUILD_CMD:-m} ravenhelper + +# Get the target directory. Default to $ANDROID_BUILD_TOP. +TARGET_DIR="${TARGET_DIR:-${ANDROID_BUILD_TOP?\$ANDROID_BUILD_TOP must be set}}" + +echo "Target dir=$TARGET_DIR" + +cd "$TARGET_DIR" + +# Add -v or -d as needed. +extra_args="$@" + +OUT_SCRIPT="${OUT_SCRIPT:-/tmp/pta.sh}" + +rm -f "$OUT_SCRIPT" + +# If you want to run on other files, run this script with the following +# env vars predefined. + +POLICIES="${POLICIES:- +frameworks/base/ravenwood/texts/ravenwood-common-policies.txt +frameworks/base/ravenwood/texts/ravenwood-framework-policies.txt +}" + +SOURCES="${SOURCES:- +frameworks/base/core/java/ +frameworks/base/graphics/java/ +}" + +AAC="${AAC:-frameworks/base/ravenwood/texts/ravenwood-annotation-allowed-classes.txt}" + +with_flag() { + local flag="$1" + shift + + for arg in "$@"; do + echo "$flag $arg" + done +} + +run() { + echo "Running: $*" + "$@" +} + +run_pta() { + local extra_args="$@" + + run ${RAVENHELPER_CMD:-ravenhelper pta} \ + --output-script $OUT_SCRIPT \ + --annotation-allowed-classes-file $AAC \ + $(with_flag --policy-override-file $POLICIES) \ + $(with_flag --src $SOURCES) \ + $extra_args + + if ! [[ -f $OUT_SCRIPT ]] ; then + # no operations generated. + exit 0 + fi + + echo + echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT" + return 0 +} + +run_pta "$extra_args"
\ No newline at end of file diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt index 83c31512eb70..fd4ea6cf40c2 100644 --- a/ravenwood/texts/ravenwood-common-policies.txt +++ b/ravenwood/texts/ravenwood-common-policies.txt @@ -1,5 +1,8 @@ # Ravenwood "policy" that should apply to all code. +# The "no-pta" marker is used to exclude the lines from "ravenhelper pta", +# which tries to convert policies to annotations. + # Keep all AIDL interfaces class :aidl keepclass @@ -13,8 +16,8 @@ class :sysprops keepclass class :r keepclass # Support APIs not available in standard JRE -class java.io.FileDescriptor keep +class java.io.FileDescriptor # no-pta method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$ method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$ -class java.util.LinkedHashMap keep +class java.util.LinkedHashMap # no-pta method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt index 26b6fe3d82ad..4033782c607e 100644 --- a/ravenwood/texts/ravenwood-framework-policies.txt +++ b/ravenwood/texts/ravenwood-framework-policies.txt @@ -1,62 +1,65 @@ # Ravenwood "policy" file for framework-minus-apex. +# The "no-pta" marker is used to exclude the lines from "ravenhelper pta", +# which tries to convert policies to annotations. + # To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes. # Note: The "rename" directive must use slashes (/) as a package name separator. rename com/.*/nano/ devicenano/ rename android/.*/nano/ devicenano/ # StatsD auto-generated -class com.android.internal.util.FrameworkStatsLog keepclass +class com.android.internal.util.FrameworkStatsLog keepclass # no-pta # Exported to Mainline modules; cannot use annotations -class com.android.internal.util.FastXmlSerializer keepclass -class com.android.internal.util.FileRotator keepclass -class com.android.internal.util.HexDump keepclass -class com.android.internal.util.IndentingPrintWriter keepclass -class com.android.internal.util.LocalLog keepclass -class com.android.internal.util.MessageUtils keepclass -class com.android.internal.util.TokenBucket keepclass -class android.os.HandlerExecutor keepclass -class android.util.BackupUtils keepclass -class android.util.IndentingPrintWriter keepclass -class android.util.LocalLog keepclass -class android.util.Pair keepclass -class android.util.Rational keepclass +class com.android.internal.util.FastXmlSerializer keepclass # no-pta +class com.android.internal.util.FileRotator keepclass # no-pta +class com.android.internal.util.HexDump keepclass # no-pta +class com.android.internal.util.IndentingPrintWriter keepclass # no-pta +class com.android.internal.util.LocalLog keepclass # no-pta +class com.android.internal.util.MessageUtils keepclass # no-pta +class com.android.internal.util.TokenBucket keepclass # no-pta +class android.os.HandlerExecutor keepclass # no-pta +class android.util.BackupUtils keepclass # no-pta +class android.util.IndentingPrintWriter keepclass # no-pta +class android.util.LocalLog keepclass # no-pta +class android.util.Pair keepclass # no-pta +class android.util.Rational keepclass # no-pta # From modules-utils; cannot use annotations -class com.android.internal.util.Preconditions keepclass -class com.android.internal.logging.InstanceId keepclass -class com.android.internal.logging.InstanceIdSequence keepclass -class com.android.internal.logging.UiEvent keepclass -class com.android.internal.logging.UiEventLogger keepclass +class com.android.internal.util.Preconditions keepclass # no-pta +class com.android.internal.logging.InstanceId keepclass # no-pta +class com.android.internal.logging.InstanceIdSequence keepclass # no-pta +class com.android.internal.logging.UiEvent keepclass # no-pta +class com.android.internal.logging.UiEventLogger keepclass # no-pta # From modules-utils; cannot use annotations -class com.android.modules.utils.BinaryXmlPullParser keepclass -class com.android.modules.utils.BinaryXmlSerializer keepclass -class com.android.modules.utils.FastDataInput keepclass -class com.android.modules.utils.FastDataOutput keepclass -class com.android.modules.utils.ModifiedUtf8 keepclass -class com.android.modules.utils.TypedXmlPullParser keepclass -class com.android.modules.utils.TypedXmlSerializer keepclass +class com.android.modules.utils.BinaryXmlPullParser keepclass # no-pta +class com.android.modules.utils.BinaryXmlSerializer keepclass # no-pta +class com.android.modules.utils.FastDataInput keepclass # no-pta +class com.android.modules.utils.FastDataOutput keepclass # no-pta +class com.android.modules.utils.ModifiedUtf8 keepclass # no-pta +class com.android.modules.utils.TypedXmlPullParser keepclass # no-pta +class com.android.modules.utils.TypedXmlSerializer keepclass # no-pta # Uri -class android.net.Uri keepclass -class android.net.UriCodec keepclass +class android.net.Uri keepclass # no-pta +class android.net.UriCodec keepclass # no-pta # Telephony -class android.telephony.PinResult keepclass +class android.telephony.PinResult keepclass # no-pta # Just enough to support mocking, no further functionality -class android.content.BroadcastReceiver keep +class android.content.BroadcastReceiver keep # no-pta method <init> ()V keep -class android.content.Context keep +class android.content.Context keep # no-pta method <init> ()V keep - method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep -class android.content.pm.PackageManager + method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep # no-pta +class android.content.pm.PackageManager # no-pta method <init> ()V keep -class android.text.ClipboardManager keep +class android.text.ClipboardManager keep # no-pta method <init> ()V keep # Just enough to allow ResourcesManager to run -class android.hardware.display.DisplayManagerGlobal keep +class android.hardware.display.DisplayManagerGlobal keep # no-pta method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore diff --git a/ravenwood/texts/ravenwood-services-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt index 530e5c8f5986..e3be9afdba5c 100644 --- a/ravenwood/texts/ravenwood-services-policies.txt +++ b/ravenwood/texts/ravenwood-services-policies.txt @@ -1,12 +1,15 @@ # Ravenwood "policy" file for services.core. +# The "no-pta" marker is used to exclude the lines from "ravenhelper pta", +# which tries to convert policies to annotations. + # Auto-generated from XSD -class com.android.server.compat.config.Change keepclass -class com.android.server.compat.config.Config keepclass -class com.android.server.compat.config.XmlParser keepclass -class com.android.server.compat.overrides.ChangeOverrides keepclass -class com.android.server.compat.overrides.OverrideValue keepclass -class com.android.server.compat.overrides.Overrides keepclass -class com.android.server.compat.overrides.RawOverrideValue keepclass -class com.android.server.compat.overrides.XmlParser keepclass -class com.android.server.compat.overrides.XmlWriter keepclass
\ No newline at end of file +class com.android.server.compat.config.Change keepclass # no-pta +class com.android.server.compat.config.Config keepclass # no-pta +class com.android.server.compat.config.XmlParser keepclass # no-pta +class com.android.server.compat.overrides.ChangeOverrides keepclass # no-pta +class com.android.server.compat.overrides.OverrideValue keepclass # no-pta +class com.android.server.compat.overrides.Overrides keepclass # no-pta +class com.android.server.compat.overrides.RawOverrideValue keepclass # no-pta +class com.android.server.compat.overrides.XmlParser keepclass # no-pta +class com.android.server.compat.overrides.XmlWriter keepclass # no-pta
\ No newline at end of file diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt index c5500831e21a..9782f3d0f591 100644 --- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt +++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt @@ -69,9 +69,9 @@ interface PolicyFileProcessor { fun onRename(pattern: Pattern, prefix: String) /** "class" directive. */ - fun onSimpleClassStart(className: String) + fun onClassStart(className: String) fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) - fun onSimpleClassEnd(className: String) + fun onClassEnd(className: String) fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason) fun onRedirectionClass(fromClassName: String, toClassName: String) @@ -162,10 +162,10 @@ class TextFileFilterPolicyBuilder( ) } - override fun onSimpleClassStart(className: String) { + override fun onClassStart(className: String) { } - override fun onSimpleClassEnd(className: String) { + override fun onClassEnd(className: String) { } override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) { @@ -273,20 +273,23 @@ class TextFileFilterPolicyParser { private var rFilePolicy: FilterPolicyWithReason? = null /** Name of the file that's currently being processed. */ - var filename: String? = null + var filename: String = "" private set /** 1-based line number in the current file */ var lineNumber = -1 private set + /** Current line */ + var currentLineText = "" + private set + /** * Parse a given "policy" file. */ fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) { filename = inputName - log.i("Parsing text policy file $inputName ...") this.processor = processor BufferedReader(reader).use { rd -> lineNumber = 0 @@ -297,6 +300,7 @@ class TextFileFilterPolicyParser { break } lineNumber++ + currentLineText = line line = normalizeTextLine(line) // Remove comment and trim. if (line.isEmpty()) { continue @@ -312,7 +316,7 @@ class TextFileFilterPolicyParser { private fun finishLastClass() { currentClassName?.let { className -> - processor.onSimpleClassEnd(className) + processor.onClassEnd(className) currentClassName = null } } @@ -416,7 +420,7 @@ class TextFileFilterPolicyParser { if (fields.size <= 1) { throw ParseException("Class ('c') expects 1 or 2 fields.") } - val className = fields[1] + val className = fields[1].toHumanReadableClassName() // superClass is set when the class name starts with a "*". val superClass = resolveExtendingClass(className) @@ -436,6 +440,8 @@ class TextFileFilterPolicyParser { // It's a redirection class. val toClass = policyStr.substring(1) + currentClassName = className + processor.onClassStart(className) processor.onRedirectionClass(className, toClass) } else if (policyStr.startsWith("~")) { if (classType != SpecialClass.NotSpecial) { @@ -447,6 +453,8 @@ class TextFileFilterPolicyParser { // It's a class-load hook val callback = policyStr.substring(1) + currentClassName = className + processor.onClassStart(className) processor.onClassLoadHook(className, callback) } else { // Special case: if it's a class directive with no policy, then it encloses @@ -455,7 +463,6 @@ class TextFileFilterPolicyParser { if (policyStr == "") { if (classType == SpecialClass.NotSpecial && superClass == null) { currentClassName = className - processor.onSimpleClassStart(className) return } throw ParseException("Special class or subclass directive must have a policy") @@ -471,7 +478,7 @@ class TextFileFilterPolicyParser { // TODO: Duplicate check, etc if (superClass == null) { currentClassName = className - processor.onSimpleClassStart(className) + processor.onClassStart(className) processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON)) } else { processor.onSubClassPolicy( diff --git a/ravenwood/tools/ravenhelper/Android.bp b/ravenwood/tools/ravenhelper/Android.bp new file mode 100644 index 000000000000..a7ee4684506e --- /dev/null +++ b/ravenwood/tools/ravenhelper/Android.bp @@ -0,0 +1,26 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +java_binary_host { + name: "ravenhelper", + main_class: "com.android.platform.test.ravenwood.ravenhelper.RavenHelperMain", + srcs: ["src/**/*.kt"], + static_libs: [ + "guava", + "hoststubgen-lib", + "junit", + "metalava-gradle-plugin-deps", // Get lint/PSI related classes from here. + "ow2-asm", + "ow2-asm-analysis", + "ow2-asm-commons", + "ow2-asm-tree", + "ow2-asm-util", + ], + visibility: ["//visibility:public"], +} diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt new file mode 100644 index 000000000000..e6efbf6c5223 --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:JvmName("RavenHelperMain") +package com.android.platform.test.ravenwood.ravenhelper + +/* + * This file contains the main entry point for the "ravenhelper" command, which + * contains subcommands to help various tasks. + */ + +import com.android.hoststubgen.GeneralUserErrorException +import com.android.hoststubgen.LogLevel +import com.android.hoststubgen.executableName +import com.android.hoststubgen.log +import com.android.hoststubgen.runMainWithBoilerplate +import com.android.platform.test.ravenwood.ravenhelper.policytoannot.PtaProcessor + +interface SubcommandHandler { + fun handle(args: List<String>) +} + +fun usage() { + System.out.println(""" + Usage: + ravenhelper SUBCOMMAND options... + + Subcommands: + pta: "policy-to-annotations" Convert policy file to annotations. + (See the pta-framework.sh script for usage.) 1 + + """.trimIndent()) +} + +fun main(args: Array<String>) { + executableName = "RavenHelper" + log.setConsoleLogLevel(LogLevel.Info) + + runMainWithBoilerplate { + log.i("$executableName started") + + if (args.size == 0) { + usage() + return + } + + // Find the subcommand handler. + val subcommand = args[0] + val handler: SubcommandHandler = when (subcommand) { + "pta" -> PtaProcessor() + else -> { + usage() + throw GeneralUserErrorException("Unknown subcommand '$subcommand'") + } + } + + // Run the subcommand. + handler.handle(args.copyOfRange(1, args.size).toList()) + } +} diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt new file mode 100644 index 000000000000..4a11259a8ef7 --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.policytoannot + +import com.android.hoststubgen.filters.FilterPolicy + + +/** + * This class knows about the Ravenwood annotations. + */ +class Annotations { + enum class Target { + Class, + Field, + Method, + } + + fun get(policy: FilterPolicy, target: Target): String? { + return when (policy) { + FilterPolicy.Keep -> + if (target == Target.Class) { + "@android.ravenwood.annotation.RavenwoodKeepPartialClass" + } else { + "@android.ravenwood.annotation.RavenwoodKeep" + } + FilterPolicy.KeepClass -> + "@android.ravenwood.annotation.RavenwoodKeepWholeClass" + FilterPolicy.Substitute -> + "@android.ravenwood.annotation.RavenwoodReplace" + FilterPolicy.Redirect -> + "@android.ravenwood.annotation.RavenwoodRedirect" + FilterPolicy.Throw -> + "@android.ravenwood.annotation.RavenwoodThrow" + FilterPolicy.Ignore -> null // Ignore has no annotation. (because it's not very safe.) + FilterPolicy.Remove -> + "@android.ravenwood.annotation.RavenwoodRemove" + } + } + + private fun withArg(annot: String, arg: String): String { + return "@$annot(\"$arg\")" + } + + fun getClassLoadHookAnnotation(arg: String): String { + return withArg("android.ravenwood.annotation.RavenwoodClassLoadHook", arg) + } + + fun getRedirectionClassAnnotation(arg: String): String { + return withArg("android.ravenwood.annotation.RavenwoodRedirectionClass", arg) + } +} + diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt new file mode 100644 index 000000000000..3531ba951b1c --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.policytoannot + +/* + * This file contains classes and functions about file edit operations, such as + * "insert a line", "delete a line". + */ + + +import com.android.hoststubgen.log +import java.io.BufferedWriter +import java.io.File + +enum class SourceOperationType { + /** Insert a line */ + Insert, + + /** delete a line */ + Delete, + + /** Insert a text at the beginning of a line */ + Prepend, +} + +data class SourceOperation( + /** Target file to edit. */ + val sourceFile: String, + + /** 1-based line number. Use -1 to add at the end of the file. */ + val lineNumber: Int, + + /** Operation type.*/ + val type: SourceOperationType, + + /** Operand -- text to insert or prepend. Ignored for delete. */ + val text: String = "", + + /** Human-readable description of why this operation was created */ + val description: String, +) { + override fun toString(): String { + return "SourceOperation(sourceFile='$sourceFile', " + + "lineNumber=$lineNumber, type=$type, text='$text' desc='$description')" + } +} + +/** + * Stores list of [SourceOperation]s for each file. + */ +class SourceOperations { + var size: Int = 0 + private set + private val fileOperations = mutableMapOf<String, MutableList<SourceOperation>>() + + fun add(op: SourceOperation) { + log.forVerbose { + log.v("Adding operation: $op") + } + size++ + fileOperations[op.sourceFile]?.let { ops -> + ops.add(op) + return + } + fileOperations[op.sourceFile] = mutableListOf(op) + } + + /** + * Get the collected [SourceOperation]s for each file. + */ + fun getOperations(): MutableMap<String, MutableList<SourceOperation>> { + return fileOperations + } +} + +/** + * Create a shell script to apply all the operations (using sed). + */ +fun createShellScript(ops: SourceOperations, writer: BufferedWriter) { + // File header. + // Note ${'$'} is an ugly way to put a dollar sign ($) in a multi-line string. + writer.write( + """ + #!/bin/bash + + set -e # Finish when any command fails. + + function apply() { + local file="${'$'}1" + + # The script is given via stdin. Write it to file. + local sed="/tmp/pta-script.sed.tmp" + cat > "${'$'}sed" + + echo "Running: sed -i -f \"${'$'}sed\" \"${'$'}file\"" + + if ! sed -i -f "${'$'}sed" "${'$'}file" ; then + echo 'Failed!' 1>&2 + return 1 + fi + } + + """.trimIndent() + ) + + ops.getOperations().toSortedMap().forEach { (origFile, ops) -> + val file = File(origFile).absolutePath + + writer.write("\n") + + writer.write("#") + writer.write("=".repeat(78)) + writer.write("\n") + + writer.write("\n") + + writer.write("apply \"$file\" <<'__END_OF_SCRIPT__'\n") + toSedScript(ops, writer) + writer.write("__END_OF_SCRIPT__\n") + } + + writer.write("\n") + + writer.write("echo \"All files updated successfully!\"\n") + writer.flush() +} + +/** + * Create a sed script to apply a list of operations. + */ +private fun toSedScript(ops: List<SourceOperation>, writer: BufferedWriter) { + ops.sortedBy { it.lineNumber }.forEach { op -> + if (op.text.contains('\n')) { + throw RuntimeException("Operation $op may not contain newlines.") + } + + // Convert each operation to a sed operation. Examples: + // + // - Insert "abc" to line 2 + // 2i\ + // abc + // + // - Insert "abc" to the end of the file + // $a\ + // abc + // + // - Delete line 2 + // 2d + // + // - Prepend abc to line 2 + // 2s/^/abc/ + // + // The line numbers are all the line numbers in the original file. Even though + // the script itself will change them because of inserts and deletes, we don't need to + // change the line numbers in the script. + + // Write the target line number. + writer.write("\n") + writer.write("# ${op.description}\n") + if (op.lineNumber >= 0) { + writer.write(op.lineNumber.toString()) + } else { + writer.write("$") + } + + when (op.type) { + SourceOperationType.Insert -> { + if (op.lineNumber >= 0) { + writer.write("i\\\n") // "Insert" + } else { + // If it's the end of the file, we need to use "a" (append) + writer.write("a\\\n") + } + writer.write(op.text) + writer.write("\n") + } + SourceOperationType.Delete -> { + writer.write("d\n") + } + SourceOperationType.Prepend -> { + if (op.text.contains('/')) { + TODO("Operation $op contains character(s) that needs to be escaped.") + } + writer.write("s/^/${op.text}/\n") + } + } + } +}
\ No newline at end of file diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt new file mode 100644 index 000000000000..08bd95fd532b --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.policytoannot + +import com.android.hoststubgen.ArgIterator +import com.android.hoststubgen.ArgumentsException +import com.android.hoststubgen.SetOnce +import com.android.hoststubgen.ensureFileExists +import com.android.hoststubgen.log + +/** + * Options for the "ravenhelper pta" subcommand. + */ +class PtaOptions( + /** Text policy files */ + var policyOverrideFiles: MutableList<String> = mutableListOf(), + + /** Annotation allowed list file. */ + var annotationAllowedClassesFile: SetOnce<String?> = SetOnce(null), + + /** Source files or directories. */ + var sourceFilesOrDirectories: MutableList<String> = mutableListOf(), + + /** Output script file. */ + var outputScriptFile: SetOnce<String?> = SetOnce(null), + + /** Dump the operations (for debugging) */ + var dumpOperations: SetOnce<Boolean> = SetOnce(false), +) { + companion object { + fun parseArgs(args: List<String>): PtaOptions { + val ret = PtaOptions() + val ai = ArgIterator.withAtFiles(args.toTypedArray()) + + while (true) { + val arg = ai.nextArgOptional() ?: break + + fun nextArg(): String = ai.nextArgRequired(arg) + + if (log.maybeHandleCommandLineArg(arg) { nextArg() }) { + continue + } + try { + when (arg) { + // TODO: Write help + "-h", "--help" -> TODO("Help is not implemented yet") + + "-p", "--policy-override-file" -> + ret.policyOverrideFiles.add(nextArg().ensureFileExists()) + + "-a", "--annotation-allowed-classes-file" -> + ret.annotationAllowedClassesFile.set(nextArg().ensureFileExists()) + + "-s", "--src" -> + ret.sourceFilesOrDirectories.add(nextArg().ensureFileExists()) + + "--dump" -> + ret.dumpOperations.set(true) + + "-o", "--output-script" -> + ret.outputScriptFile.set(nextArg()) + + else -> throw ArgumentsException("Unknown option: $arg") + } + } catch (e: SetOnce.SetMoreThanOnceException) { + throw ArgumentsException("Duplicate or conflicting argument found: $arg") + } + } + + if (ret.policyOverrideFiles.size == 0) { + throw ArgumentsException("Must specify at least one policy file") + } + + if (ret.sourceFilesOrDirectories.size == 0) { + throw ArgumentsException("Must specify at least one source path") + } + + return ret + } + } + + override fun toString(): String { + return """ + PtaOptions{ + policyOverrideFiles=$policyOverrideFiles + annotationAllowedClassesFile=$annotationAllowedClassesFile + sourceFilesOrDirectories=$sourceFilesOrDirectories + outputScriptFile=$outputScriptFile + dumpOperations=$dumpOperations + } + """.trimIndent() + } +}
\ No newline at end of file diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt new file mode 100644 index 000000000000..5984e4fc8f9f --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt @@ -0,0 +1,479 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.policytoannot + +import com.android.hoststubgen.LogLevel +import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME +import com.android.hoststubgen.asm.toJvmClassName +import com.android.hoststubgen.filters.FilterPolicyWithReason +import com.android.hoststubgen.filters.PolicyFileProcessor +import com.android.hoststubgen.filters.SpecialClass +import com.android.hoststubgen.filters.TextFileFilterPolicyParser +import com.android.hoststubgen.filters.TextFilePolicyMethodReplaceFilter +import com.android.hoststubgen.log +import com.android.hoststubgen.utils.ClassFilter +import com.android.platform.test.ravenwood.ravenhelper.SubcommandHandler +import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment +import com.android.platform.test.ravenwood.ravenhelper.sourcemap.AllClassInfo +import com.android.platform.test.ravenwood.ravenhelper.sourcemap.ClassInfo +import com.android.platform.test.ravenwood.ravenhelper.sourcemap.MethodInfo +import com.android.platform.test.ravenwood.ravenhelper.sourcemap.SourceLoader +import java.io.BufferedWriter +import java.io.FileOutputStream +import java.io.FileReader +import java.io.OutputStreamWriter +import java.util.regex.Pattern + +/** + * This is the main routine of the "pta" -- policy-to-annotation -- subcommands. + */ +class PtaProcessor : SubcommandHandler { + override fun handle(args: List<String>) { + val options = PtaOptions.parseArgs(args) + + log.v("Options: $options") + + val converter = TextPolicyToAnnotationConverter( + options.policyOverrideFiles, + options.sourceFilesOrDirectories, + options.annotationAllowedClassesFile.get, + Annotations(), + options.dumpOperations.get || log.isEnabled(LogLevel.Debug), + ) + converter.process() + + val ops = converter.resultOperations + + if (ops.size == 0) { + log.i("No files need to be updated.") + return + } + + val scriptWriter = BufferedWriter(OutputStreamWriter( + options.outputScriptFile.get?.let { file -> + FileOutputStream(file) + } ?: System.out + )) + + scriptWriter.use { writer -> + options.outputScriptFile.get?.let { + log.i("Creating script file at $it ...") + } + createShellScript(ops, writer) + } + } +} + +/** + * This class implements the actual logic. + */ +private class TextPolicyToAnnotationConverter( + val policyFiles: List<String>, + val sourceFilesOrDirectories: List<String>, + val annotationAllowedClassesFile: String?, + val annotations: Annotations, + val dumpOperations: Boolean, +) { + private val annotationAllowedClasses: ClassFilter = annotationAllowedClassesFile.let { file -> + if (file == null) { + ClassFilter.newNullFilter(true) // Allow all classes + } else { + ClassFilter.loadFromFile(file, false) + } + } + + val resultOperations = SourceOperations() + private val classes = AllClassInfo() + private val policyParser = TextFileFilterPolicyParser() + private val annotationNeedingClasses = mutableSetOf<String>() + + /** + * Entry point. + */ + fun process() { + // First, load + val env = createUastEnvironment() + try { + loadSources() + + processPolicies() + + addToAnnotationsAllowedListFile() + + if (dumpOperations) { + log.withIndent { + resultOperations.getOperations().toSortedMap().forEach { (file, ops) -> + log.i("ops: $file") + ops.forEach { op -> + log.i(" line: ${op.lineNumber}: ${op.type}: \"${op.text}\" " + + "(${op.description})") + } + } + } + } + } finally { + env.dispose() + } + } + + /** + * Load all the java source files into [classes]. + */ + private fun loadSources() { + val env = createUastEnvironment() + try { + val loader = SourceLoader(env) + loader.load(sourceFilesOrDirectories, classes) + } finally { + env.dispose() + } + } + + private fun addToAnnotationsAllowedListFile() { + log.i("Generating operations to update annotation allowlist file...") + log.withIndent { + annotationNeedingClasses.sorted().forEach { className -> + if (!annotationAllowedClasses.matches(className.toJvmClassName())) { + resultOperations.add( + SourceOperation( + annotationAllowedClassesFile!!, + -1, // add to the end + SourceOperationType.Insert, + className, + "add to annotation allowlist" + )) + } + } + } + } + + /** + * Process the policy files with [Processor]. + */ + private fun processPolicies() { + log.i("Loading the policy files and generating operations...") + log.withIndent { + policyFiles.forEach { policyFile -> + log.i("Parsing $policyFile ...") + log.withIndent { + policyParser.parse(FileReader(policyFile), policyFile, Processor()) + } + } + } + } + + private inner class Processor : PolicyFileProcessor { + + var classPolicyText = "" + var classPolicyLine = -1 + + // Whether the current class has a skip marker, in which case we ignore all members. + // Applicable only within a "simple class" + var classSkipping = false + + var classLineConverted = false + var classHasMember = false + + private fun currentLineHasSkipMarker(): Boolean { + val ret = policyParser.currentLineText.contains("no-pta") + + if (ret) { + log.forVerbose { + log.v("Current line has a skip marker: ${policyParser.currentLineText}") + } + } + + return ret + } + + private fun shouldSkipCurrentLine(): Boolean { + // If a line contains a special marker "no-pta", we'll skip it. + return classSkipping || currentLineHasSkipMarker() + } + + /** Print a warning about an unsupported policy directive. */ + private fun warnOnPolicy(message: String, policyLine: String, lineNumber: Int) { + log.w("Warning: $message") + log.w(" policy: \"$policyLine\"") + log.w(" at ${policyParser.filename}:$lineNumber") + } + + /** Print a warning about an unsupported policy directive. */ + private fun warnOnCurrentPolicy(message: String) { + warnOnPolicy(message, policyParser.currentLineText, policyParser.lineNumber) + } + + /** Print a warning about an unsupported policy directive on the class line. */ + private fun warnOnClassPolicy(message: String) { + warnOnPolicy(message, classPolicyText, classPolicyLine) + } + + override fun onPackage(name: String, policy: FilterPolicyWithReason) { + warnOnCurrentPolicy("'package' directive isn't supported (yet).") + } + + override fun onRename(pattern: Pattern, prefix: String) { + // Rename will never be supported, so don't show a warning. + } + + private fun addOperation(op: SourceOperation) { + resultOperations.add(op) + } + + private fun commentOutPolicy(lineNumber: Int, description: String) { + addOperation( + SourceOperation( + policyParser.filename, + lineNumber, + SourceOperationType.Prepend, + "#[PTA]: ", // comment out. + description, + ) + ) + } + + override fun onClassStart(className: String) { + classSkipping = currentLineHasSkipMarker() + classLineConverted = false + classHasMember = false + classPolicyLine = policyParser.lineNumber + classPolicyText = policyParser.currentLineText + } + + override fun onClassEnd(className: String) { + if (classSkipping) { + classSkipping = false + return + } + if (!classLineConverted) { + // Class line is still needed in the policy file. + // (Because the source file wasn't found.) + return + } + if (!classHasMember) { + commentOutPolicy(classPolicyLine, "remove class policy on $className") + } else { + warnOnClassPolicy( + "Class policy on $className can't be removed because it still has members.") + } + } + + private fun findClass(className: String): ClassInfo? { + val ci = classes.findClass(className) + if (ci == null) { + warnOnCurrentPolicy("Class not found: $className") + } + return ci + } + + private fun addClassAnnotation( + className: String, + annotation: String, + ): Boolean { + val ci = findClass(className) ?: return false + + // Add the annotation to the source file. + addOperation( + SourceOperation( + ci.location.file, + ci.location.line, + SourceOperationType.Insert, + ci.location.getIndent() + annotation, + "add class annotation to $className" + ) + ) + annotationNeedingClasses.add(className) + return true + } + + override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) { + if (shouldSkipCurrentLine()) { + return + } + log.v("Found simple class policy: $className - ${policy.policy}") + + val annot = annotations.get(policy.policy, Annotations.Target.Class)!! + if (addClassAnnotation(className, annot)) { + classLineConverted = true + } + } + + override fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason) { + warnOnCurrentPolicy("Subclass policies isn't supported (yet).") + } + + override fun onRedirectionClass(fromClassName: String, toClassName: String) { + if (shouldSkipCurrentLine()) { + return + } + + log.v("Found class redirection: $fromClassName - $toClassName") + + if (addClassAnnotation( + fromClassName, + annotations.getRedirectionClassAnnotation(toClassName), + )) { + commentOutPolicy(policyParser.lineNumber, + "remove class redirection policy on $fromClassName") + } + } + + override fun onClassLoadHook(className: String, callback: String) { + if (shouldSkipCurrentLine()) { + return + } + + log.v("Found class load hook: $className - $callback") + + if (addClassAnnotation( + className, + annotations.getClassLoadHookAnnotation(callback), + )) { + commentOutPolicy(policyParser.lineNumber, + "remove class load hook policy on $className") + } + } + + override fun onSpecialClassPolicy(type: SpecialClass, policy: FilterPolicyWithReason) { + // This can't be converted to an annotation, so don't show a warning. + } + + override fun onField(className: String, fieldName: String, policy: FilterPolicyWithReason) { + if (shouldSkipCurrentLine()) { + return + } + + log.v("Found field policy: $className.$fieldName - ${policy.policy}") + + val ci = findClass(className) ?: return + + ci.findField(fieldName)?.let { fi -> + val annot = annotations.get(policy.policy, Annotations.Target.Field)!! + + addOperation( + SourceOperation( + fi.location.file, + fi.location.line, + SourceOperationType.Insert, + fi.location.getIndent() + annot, + "add annotation to field $className.$fieldName", + ) + ) + commentOutPolicy(policyParser.lineNumber, + "remove field policy $className.$fieldName") + + annotationNeedingClasses.add(className) + } ?: { + warnOnCurrentPolicy("Field not found: $className.$fieldName") + } + } + + override fun onSimpleMethodPolicy( + className: String, + methodName: String, + methodDesc: String, + policy: FilterPolicyWithReason + ) { + if (shouldSkipCurrentLine()) { + return + } + val readableName = "$className.$methodName$methodDesc" + log.v("Found simple method policy: $readableName - ${policy.policy}") + + + // Inner method to get the matching methods for this policy. + // + // If this policy can't be converted for any reason, it'll return null. + // Otherwise, it'll return a pair of method list and the annotation string. + fun getMethods(): Pair<List<MethodInfo>, String>? { + if (methodName == CLASS_INITIALIZER_NAME) { + warnOnClassPolicy("Policy for class initializers not supported.") + return null + } + val ci = findClass(className) ?: return null + val methods = ci.findMethods(methodName, methodDesc) + if (methods == null) { + warnOnCurrentPolicy("Method not found: $readableName") + return null + } + + // If the policy is "ignore", we can't convert it to an annotation, in which case + // annotations.get() will return null. + val annot = annotations.get(policy.policy, Annotations.Target.Method) + if (annot == null) { + warnOnCurrentPolicy("Annotation for policy '${policy.policy}' isn't available") + return null + } + return Pair(methods, annot) + } + + val methodsAndAnnot = getMethods() + + if (methodsAndAnnot == null) { + classHasMember = true + return // This policy can't converted. + } + val methods = methodsAndAnnot.first + val annot = methodsAndAnnot.second + + var found = false + methods.forEach { mi -> + found = true + addOperation( + SourceOperation( + mi.location.file, + mi.location.line, + SourceOperationType.Insert, + mi.location.getIndent() + annot, + "add annotation to method $readableName", + ) + ) + } + if (found) { + commentOutPolicy( + policyParser.lineNumber, + "remove method policy $readableName" + ) + + annotationNeedingClasses.add(className) + } else { + warnOnCurrentPolicy("Method not found: $readableName") + } + } + + override fun onMethodInClassReplace( + className: String, + methodName: String, + methodDesc: String, + targetName: String, + policy: FilterPolicyWithReason + ) { + warnOnCurrentPolicy("Found method replace but it's not supported yet: " + + "$className.$methodName$methodDesc - $targetName") + } + + override fun onMethodOutClassReplace( + className: String, + methodName: String, + methodDesc: String, + replaceSpec: TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec, + policy: FilterPolicyWithReason + ) { + // This can't be converted to an annotation. + classHasMember = true + } + } +}
\ No newline at end of file diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt new file mode 100644 index 000000000000..6775135e1ac5 --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.psi + +import com.android.tools.lint.UastEnvironment + +// PSI is a library to parse Java/Kotlin source files, which is part of JetBrains' IntelliJ/ +// Android Studio, and other IDEs. +// +// PSI is normally used by IntelliJ's plugins, and as such, there isn't really a good documentation +// on how to use it from a standalone program. However, fortunately, Android Studio's Lint +// and Metalava both use PSI. Metalava reuses some of the APIs exposed by Lint. We also use the +// same Lint APIs used by Metalava here. +// +// Some code pointers around the relevant projects: +// +// - We stole code from Metalava, but the recent version of Metalava is too complicated, +// and hard to understand. Older Metalava, such as this one: +// https://android.git.corp.google.com/platform/tools/metalava/+/refs/heads/android13-dev +// is easier to understand. +// +// - PSI is source code is available in IntelliJ's code base: +// https://github.com/JetBrains/intellij-community.git +// +// - Lint is in Android studio. +// https://android.googlesource.com/platform/tools/base/+/studio-master-dev/source.md + + +/** + * Create [UastEnvironment] enough to parse Java source files. + */ +fun createUastEnvironment(): UastEnvironment { + val config = UastEnvironment.Configuration.create( + enableKotlinScripting = false, + useFirUast = false, + ) + + config.javaLanguageLevel = com.intellij.pom.java.LanguageLevel.JDK_21 + + // The following code exists in Metalava, but we don't seem to need it. + // We may need to when we need to support kotlin. +// config.kotlinLanguageLevel = kotlinLanguageLevel +// config.addSourceRoots(listOf(File(root))) +// config.addClasspathRoots(classpath.map { it.absoluteFile }) +// options.jdkHome?.let { +// if (options.isJdkModular(it)) { +// config.kotlinCompilerConfig.put(JVMConfigurationKeys.JDK_HOME, it) +// config.kotlinCompilerConfig.put(JVMConfigurationKeys.NO_JDK, false) +// } +// } + + return UastEnvironment.create(config) +} diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt new file mode 100644 index 000000000000..58e4497f9f9c --- /dev/null +++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2025 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.platform.test.ravenwood.ravenhelper.sourcemap + +/* + * This file contains classes used to parse Java source files to build "source map" which + * basically tells you what classes/methods/fields are declared in what line of what file. + */ + +import com.android.hoststubgen.GeneralUserErrorException +import com.android.hoststubgen.log +import com.android.tools.lint.UastEnvironment +import com.intellij.openapi.editor.Document +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiClassOwner +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiManager +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiNameIdentifierOwner +import com.intellij.psi.SyntheticElement +import java.io.File + + +/** + * Represents the location of an item. (class, field or method) + */ +data class Location ( + /** Full path filename. */ + val file: String, + + /** 1-based line number */ + val line: Int, + + /** Indent of the line */ + val indent: Int, +) { + + fun getIndent(): String { + return " ".repeat(indent) + } + + fun dump() { + log.i("Location: $file:$line (indent: $indent)") + } +} + +/** + * Represents the type of item. + */ +enum class ItemType { + Class, + Field, + Method, +} + +/** Holds a field's location. */ +data class FieldInfo ( + val name: String, + val location: Location, +) { + fun dump() { + log.i("Field: $name") + log.withIndent { + location.dump() + } + } +} + +/** Holds a method's location. */ +data class MethodInfo ( + val name: String, + /** "Simplified" description. */ + val simpleDesc: String, + val location: Location, +) { + fun dump() { + log.i("Method: $name$simpleDesc") + log.withIndent { + location.dump() + } + } +} + +/** Holds a class's location and members. */ +data class ClassInfo ( + val fullName: String, + val location: Location, + val fields: MutableMap<String, FieldInfo> = mutableMapOf(), + val methods: MutableMap<String, MutableList<MethodInfo>> = mutableMapOf(), +) { + fun add(fi: FieldInfo) { + fields.put(fi.name, fi) + } + + fun add(mi: MethodInfo) { + val list = methods.get(mi.name) + if (list != null) { + list.add(mi) + } else { + methods.put(mi.name, mutableListOf(mi)) + } + } + + fun dump() { + log.i("Class: $fullName") + log.withIndent { + location.dump() + + // Sort and print fields and methods. + methods.toSortedMap().forEach { entry -> + entry.value.sortedBy { method -> method.simpleDesc }.forEach { + it.dump() + } + } + } + } + + /** Find a field by name */ + fun findField(fieldName: String): FieldInfo? { + return fields[fieldName] + } + + /** + * Find a field by name and descriptor. + * + * If [descriptor] is "*", then all methods with the name will be returned. + */ + fun findMethods(methodName: String, methodDesc: String): List<MethodInfo>? { + val list = methods[methodName] ?: return null + + // Wildcard method policy. + if (methodDesc == "*") { + return list + } + + val simpleDesc = simplifyMethodDesc(methodDesc) + list.forEach { mi -> + if (simpleDesc == mi.simpleDesc) { + return listOf(mi) + } + } + log.w("Method $fullName.$methodName found, but none match description '$methodDesc'") + return null + } +} + +/** + * Stores all classes + */ +data class AllClassInfo ( + val classes: MutableMap<String, ClassInfo> = mutableMapOf(), +) { + fun add(ci: ClassInfo) { + classes.put(ci.fullName, ci) + } + + fun dump() { + classes.toSortedMap { a, b -> a.compareTo(b) }.forEach { + it.value.dump() + } + } + + fun findClass(name: String): ClassInfo? { + return classes.get(name) + } +} + +fun typeToSimpleDesc(origType: String): String { + var type = origType + + // Detect arrays. + var arrayPrefix = "" + while (type.endsWith("[]")) { + arrayPrefix += "[" + type = type.substring(0, type.length - 2) + } + + // Delete generic parameters. (delete everything after '<') + type.indexOf('<').let { pos -> + if (pos >= 0) { + type = type.substring(0, pos) + } + } + + // Handle builtins. + val builtinType = when (type) { + "byte" -> "B" + "short" -> "S" + "int" -> "I" + "long" -> "J" + "float" -> "F" + "double" -> "D" + "boolean" -> "Z" + "char" -> "C" + "void" -> "V" + else -> null + } + + builtinType?.let { + return arrayPrefix + builtinType + } + + return arrayPrefix + "L" + type + ";" +} + +/** + * Get a "simple" description of a method. + * + * "Simple" descriptions are similar to "real" ones, except: + * - No return type. + * - No package names in type names. + */ +fun getSimpleDesc(method: PsiMethod): String { + val sb = StringBuilder() + + sb.append("(") + + val params = method.parameterList + for (i in 0..<params.parametersCount) { + val param = params.getParameter(i) + + val type = param?.type?.presentableText + + if (type == null) { + throw RuntimeException( + "Unable to decode parameter list from method from ${params.parent}") + } + + sb.append(typeToSimpleDesc(type)) + } + + sb.append(")") + + return sb.toString() +} + +private val reTypeFinder = "L.*/".toRegex() + +private fun simplifyMethodDesc(origMethodDesc: String): String { + // We don't need the return type, so remove everything after the ')'. + val pos = origMethodDesc.indexOf(')') + var desc = if (pos < 0) { origMethodDesc } else { origMethodDesc.substring(0, pos + 1) } + + // Then we remove the package names from all the class names. + // i.e. convert "Ljava/lang/String" to "LString". + + return desc.replace(reTypeFinder, "L") +} + +/** + * Class that reads and parses java source files using PSI and populate [AllClassInfo]. + */ +class SourceLoader( + val environment: UastEnvironment, +) { + private val fileSystem = StandardFileSystems.local() + private val manager = PsiManager.getInstance(environment.ideaProject) + + /** Classes that were parsed */ + private var numParsedClasses = 0 + + /** + * Main entry point. + */ + fun load(filesOrDirectories: List<String>, classes: AllClassInfo) { + val psiFiles = mutableListOf<PsiFile>() + log.i("Loading source files...") + log.iTime("Discovering source files") { + load(filesOrDirectories.map { File(it) }, psiFiles) + } + + log.i("${psiFiles.size} file(s) found.") + + if (psiFiles.size == 0) { + throw GeneralUserErrorException("No source files found.") + } + + log.iTime("Parsing source files") { + log.withIndent { + for (file in psiFiles.asSequence().distinct()) { + val classesInFile = (file as? PsiClassOwner)?.classes?.toList() + classesInFile?.forEach { clazz -> + loadClass(clazz)?.let { classes.add(it) } + + clazz.innerClasses.forEach { inner -> + loadClass(inner)?.let { classes.add(it) } + } + } + } + } + } + log.i("$numParsedClasses class(es) found.") + } + + private fun load(filesOrDirectories: List<File>, result: MutableList<PsiFile>) { + filesOrDirectories.forEach { + load(it, result) + } + } + + private fun load(file: File, result: MutableList<PsiFile>) { + if (file.isDirectory) { + file.listFiles()?.forEach { child -> + load(child, result) + } + return + } + + // It's a file + when (file.extension) { + "java" -> { + // Load it. + } + "kt" -> { + log.w("Kotlin not supported, not loading ${file.path}") + return + } + else -> return // Silently skip + } + fileSystem.findFileByPath(file.path)?.let { virtualFile -> + manager.findFile(virtualFile)?.let { psiFile -> + result.add(psiFile) + } + } + } + + private fun loadClass(clazz: PsiClass): ClassInfo? { + if (clazz is SyntheticElement) { + return null + } + log.forVerbose { + log.v("Class found: ${clazz.qualifiedName}") + } + numParsedClasses++ + + log.withIndent { + val ci = ClassInfo( + clazz.qualifiedName!!, + getLocation(clazz) ?: return null, + ) + + // Load fields. + clazz.fields.filter { it !is SyntheticElement }.forEach { + val name = it.name + log.forDebug { log.d("Field found: $name") } + val loc = getLocation(it) ?: return@forEach + ci.add(FieldInfo(name, loc)) + } + + // Load methods. + clazz.methods.filter { it !is SyntheticElement }.forEach { + val name = resolveMethodName(it) + val simpleDesc = getSimpleDesc(it) + log.forDebug { log.d("Method found: $name$simpleDesc") } + val loc = getLocation(it) ?: return@forEach + ci.add(MethodInfo(name, simpleDesc, loc)) + } + return ci + } + } + + private fun resolveMethodName(method: PsiMethod): String { + val clazz = method.containingClass!! + if (clazz.name == method.name) { + return "<init>" // It's a constructor. + } + return method.name + } + + private fun getLocation(elem: PsiElement): Location? { + val lineAndIndent = getLineNumberAndIndent(elem) + if (lineAndIndent == null) { + log.w("Unable to determine location of $elem") + return null + } + return Location( + elem.containingFile.originalFile.virtualFile.path, + lineAndIndent.first, + lineAndIndent.second, + ) + } + + private fun getLineNumberAndIndent(element: PsiElement): Pair<Int, Int>? { + val psiFile: PsiFile = element.containingFile ?: return null + val document: Document = psiFile.viewProvider.document ?: return null + + // Actual elements such as PsiClass, PsiMethod and PsiField contains the leading + // javadoc, etc, so use the "identifier"'s element, if available. + // For synthesized elements, this may return null. + val targetRange = ( + (element as PsiNameIdentifierOwner).nameIdentifier?.textRange ?: element.textRange + ) ?: return null + val lineNumber = document.getLineNumber(targetRange.startOffset) + val lineStartOffset = document.getLineStartOffset(lineNumber) + + val lineLeadingText = document.getText( + com.intellij.openapi.util.TextRange(lineStartOffset, targetRange.startOffset)) + + val indent = lineLeadingText.takeWhile { it.isWhitespace() }.length + + // Line numbers are 0-based, add 1 for human-readable format + return Pair(lineNumber + 1, indent) + } +}
\ No newline at end of file diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index 79888b051c54..70c4c1311fc9 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -21,14 +21,14 @@ import static android.view.MotionEvent.ACTION_SCROLL; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY; +import static com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures; + import android.accessibilityservice.AccessibilityTrace; import android.annotation.MainThread; import android.annotation.NonNull; import android.content.Context; import android.graphics.Region; import android.hardware.input.InputManager; -import android.hardware.input.KeyGestureEvent; -import android.os.IBinder; import android.os.Looper; import android.os.PowerManager; import android.os.SystemClock; @@ -46,15 +46,13 @@ import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; import android.view.accessibility.AccessibilityEvent; -import androidx.annotation.Nullable; - import com.android.server.LocalServices; import com.android.server.accessibility.gestures.TouchExplorer; import com.android.server.accessibility.magnification.FullScreenMagnificationController; import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler; import com.android.server.accessibility.magnification.FullScreenMagnificationVibrationHelper; -import com.android.server.accessibility.magnification.MagnificationController; import com.android.server.accessibility.magnification.MagnificationGestureHandler; +import com.android.server.accessibility.magnification.MagnificationKeyHandler; import com.android.server.accessibility.magnification.MouseEventHandler; import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler; import com.android.server.accessibility.magnification.WindowMagnificationPromptController; @@ -209,6 +207,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo private MouseKeysInterceptor mMouseKeysInterceptor; + private MagnificationKeyHandler mMagnificationKeyHandler; + private boolean mInstalled; private int mUserId; @@ -235,74 +235,6 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo */ private MotionEvent mLastActiveDeviceMotionEvent = null; - private boolean mKeyGestureEventHandlerInstalled = false; - private InputManager.KeyGestureEventHandler mKeyGestureEventHandler = - new InputManager.KeyGestureEventHandler() { - @Override - public boolean handleKeyGestureEvent( - @NonNull KeyGestureEvent event, - @Nullable IBinder focusedToken) { - final boolean complete = - event.getAction() == KeyGestureEvent.ACTION_GESTURE_COMPLETE - && !event.isCancelled(); - - // TODO(b/355499907): Receive and handle held key gestures, which can be used - // for continuous scaling and panning. In addition, handle multiple pan gestures - // at the same time (e.g. user may try to pan diagonally) reasonably, including - // decreasing diagonal movement by sqrt(2) to make it appear the same speed - // as non-diagonal movement. - - if (!complete) { - return false; - } - - final int gestureType = event.getKeyGestureType(); - final int displayId = isDisplayIdValid(event.getDisplayId()) - ? event.getDisplayId() : Display.DEFAULT_DISPLAY; - - switch (gestureType) { - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN: - mAms.getMagnificationController().scaleMagnificationByStep( - displayId, MagnificationController.ZOOM_DIRECTION_IN); - return true; - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT: - mAms.getMagnificationController().scaleMagnificationByStep( - displayId, MagnificationController.ZOOM_DIRECTION_OUT); - return true; - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT: - mAms.getMagnificationController().panMagnificationByStep( - displayId, MagnificationController.PAN_DIRECTION_LEFT); - return true; - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT: - mAms.getMagnificationController().panMagnificationByStep( - displayId, MagnificationController.PAN_DIRECTION_RIGHT); - return true; - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP: - mAms.getMagnificationController().panMagnificationByStep( - displayId, MagnificationController.PAN_DIRECTION_UP); - return true; - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN: - mAms.getMagnificationController().panMagnificationByStep( - displayId, MagnificationController.PAN_DIRECTION_DOWN); - return true; - } - return false; - } - - @Override - public boolean isKeyGestureSupported(int gestureType) { - return switch (gestureType) { - case KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN -> true; - default -> false; - }; - } - }; - private static MotionEvent cancelMotion(MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_CANCEL || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT @@ -787,20 +719,11 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo }); } - if ((mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 - || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_SINGLE_FINGER_TRIPLE_TAP) != 0) - || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP) != 0) - || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0)) { + if (isAnyMagnificationEnabled()) { final MagnificationGestureHandler magnificationGestureHandler = createMagnificationGestureHandler(displayId, displayContext); addFirstEventHandler(displayId, magnificationGestureHandler); mMagnificationGestureHandler.put(displayId, magnificationGestureHandler); - - if (com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures() - && !mKeyGestureEventHandlerInstalled) { - mInputManager.registerKeyGestureEventHandler(mKeyGestureEventHandler); - mKeyGestureEventHandlerInstalled = true; - } } if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) { @@ -817,6 +740,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo } if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) { + // mKeyboardInterceptor does not forward KeyEvents to other EventStreamTransformations, + // so it must be the last EventStreamTransformation for key events in the list. mKeyboardInterceptor = new KeyboardInterceptor(mAms, LocalServices.getService(WindowManagerPolicy.class)); // Since the display id of KeyEvent always would be -1 and it would be dispatched to @@ -832,6 +757,19 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo Display.DEFAULT_DISPLAY); addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor); } + + if (enableTalkbackAndMagnifierKeyGestures() && isAnyMagnificationEnabled()) { + mMagnificationKeyHandler = new MagnificationKeyHandler( + mAms.getMagnificationController()); + addFirstEventHandler(Display.DEFAULT_DISPLAY, mMagnificationKeyHandler); + } + } + + private boolean isAnyMagnificationEnabled() { + return (mEnabledFeatures & FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER) != 0 + || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_SINGLE_FINGER_TRIPLE_TAP) != 0) + || ((mEnabledFeatures & FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP) != 0) + || ((mEnabledFeatures & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0); } /** @@ -921,9 +859,9 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo mMouseKeysInterceptor = null; } - if (mKeyGestureEventHandlerInstalled) { - mInputManager.unregisterKeyGestureEventHandler(mKeyGestureEventHandler); - mKeyGestureEventHandlerInstalled = false; + if (mMagnificationKeyHandler != null) { + mMagnificationKeyHandler.onDestroy(); + mMagnificationKeyHandler = null; } } @@ -1365,6 +1303,8 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo joiner.add("AutoclickController"); } else if (next instanceof MotionEventInjector) { joiner.add("MotionEventInjector"); + } else if (next instanceof MagnificationKeyHandler) { + joiner.add("MagnificationKeyHandler"); } next = next.getNext(); } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 7275881e9661..875b655fe3d2 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -35,8 +35,6 @@ import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATIO import static android.accessibilityservice.AccessibilityTrace.FLAGS_PACKAGE_BROADCAST_RECEIVER; import static android.accessibilityservice.AccessibilityTrace.FLAGS_USER_BROADCAST_RECEIVER; import static android.accessibilityservice.AccessibilityTrace.FLAGS_WINDOW_MANAGER_INTERNAL; -import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; -import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.content.Context.DEVICE_ID_DEFAULT; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE; @@ -1116,22 +1114,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub mContext.registerReceiverAsUser( receiver, UserHandle.ALL, filter, null, mMainHandler, Context.RECEIVER_EXPORTED); - - if (!android.companion.virtual.flags.Flags.vdmPublicApis()) { - final BroadcastReceiver virtualDeviceReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final int deviceId = intent.getIntExtra( - EXTRA_VIRTUAL_DEVICE_ID, DEVICE_ID_DEFAULT); - mProxyManager.clearConnections(deviceId); - } - }; - - final IntentFilter virtualDeviceFilter = new IntentFilter( - ACTION_VIRTUAL_DEVICE_REMOVED); - mContext.registerReceiver(virtualDeviceReceiver, virtualDeviceFilter, - Context.RECEIVER_NOT_EXPORTED); - } } /** diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java index f8551457d04d..8adee24c7143 100644 --- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java +++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java @@ -217,7 +217,7 @@ public class ProxyManager { private void registerVirtualDeviceListener() { VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class); - if (vdm == null || !android.companion.virtual.flags.Flags.vdmPublicApis()) { + if (vdm == null) { return; } if (mVirtualDeviceListener == null) { @@ -234,7 +234,7 @@ public class ProxyManager { private void unregisterVirtualDeviceListener() { VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class); - if (vdm == null || !android.companion.virtual.flags.Flags.vdmPublicApis()) { + if (vdm == null) { return; } vdm.unregisterVirtualDeviceListener(mVirtualDeviceListener); diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java index 2e131b696afc..75ec8ea88ace 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java @@ -84,7 +84,7 @@ import java.util.concurrent.Executor; * is done and before invoking {@link TransitionCallBack#onResult}. */ public class MagnificationController implements MagnificationConnectionManager.Callback, - MagnificationGestureHandler.Callback, + MagnificationGestureHandler.Callback, MagnificationKeyHandler.Callback, FullScreenMagnificationController.MagnificationInfoChangedCallback, WindowManagerInternal.AccessibilityControllerInternal.UiChangesForAccessibilityCallbacks { @@ -347,6 +347,36 @@ public class MagnificationController implements MagnificationConnectionManager.C handleUserInteractionChanged(displayId, mode); } + @Override + public void onPanMagnificationStart(int displayId, + @MagnificationController.PanDirection int direction) { + // TODO(b/355499907): Handle multiple pan gestures at the same time (e.g. user may try to + // pan diagonally) by decreasing diagonal movement by sqrt(2) to make it appear the same + // speed as non-diagonal movement. + panMagnificationByStep(displayId, direction); + } + + @Override + public void onPanMagnificationStop(int displayId, + @MagnificationController.PanDirection int direction) { + // TODO(b/388847283): Handle held key gestures, which can be used + // for continuous scaling and panning, until they are released. + + } + + @Override + public void onScaleMagnificationStart(int displayId, + @MagnificationController.ZoomDirection int direction) { + scaleMagnificationByStep(displayId, direction); + } + + @Override + public void onScaleMagnificationStop(int displayId, + @MagnificationController.ZoomDirection int direction) { + // TODO(b/388847283): Handle held key gestures, which can be used + // for continuous scaling and panning, until they are released. + } + private void handleUserInteractionChanged(int displayId, int mode) { if (mMagnificationCapabilities != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL) { return; diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java new file mode 100644 index 000000000000..a65580c82124 --- /dev/null +++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationKeyHandler.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.accessibility.magnification; + +import android.view.Display; +import android.view.KeyEvent; + +import com.android.server.accessibility.BaseEventStreamTransformation; + +/* + * A class that listens to key presses used to control magnification. + */ +public class MagnificationKeyHandler extends BaseEventStreamTransformation { + + /** Callback interface to report that a user is intending to interact with Magnification. */ + public interface Callback { + /** + * Called when a keyboard shortcut to pan magnification in direction {@code direction} is + * pressed by a user. Note that this can be called for multiple directions if multiple + * arrows are pressed at the same time (e.g. diagonal panning). + * + * @param displayId The logical display ID + * @param direction The direction to start panning + */ + void onPanMagnificationStart(int displayId, + @MagnificationController.PanDirection int direction); + + /** + * Called when a keyboard shortcut to pan magnification in direction {@code direction} is + * unpressed by a user. Note that this can be called for multiple directions if multiple + * arrows had been pressed at the same time (e.g. diagonal panning). + * + * @param displayId The logical display ID + * @param direction The direction in which panning stopped + */ + void onPanMagnificationStop(int displayId, + @MagnificationController.PanDirection int direction); + + /** + * Called when a keyboard shortcut to scale magnification in direction `direction` is + * pressed by a user. + * + * @param displayId The logical display ID + * @param direction The direction in which scaling started + */ + void onScaleMagnificationStart(int displayId, + @MagnificationController.ZoomDirection int direction); + + /** + * Called when a keyboard shortcut to scale magnification in direction `direction` is + * unpressed by a user. + * + * @param displayId The logical display ID + * @param direction The direction in which scaling stopped + */ + void onScaleMagnificationStop(int displayId, + @MagnificationController.ZoomDirection int direction); + } + + protected final MagnificationKeyHandler.Callback mCallback; + + public MagnificationKeyHandler(Callback callback) { + mCallback = callback; + } + + @Override + public void onKeyEvent(KeyEvent event, int policyFlags) { + if (!com.android.hardware.input.Flags.enableTalkbackAndMagnifierKeyGestures()) { + // Send to the rest of the handlers. + super.onKeyEvent(event, policyFlags); + return; + } + boolean modifiersPressed = event.isAltPressed() && event.isMetaPressed(); + if (!modifiersPressed) { + super.onKeyEvent(event, policyFlags); + return; + } + boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN; + int keyCode = event.getKeyCode(); + if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT + || keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + int panDirection = switch(keyCode) { + case KeyEvent.KEYCODE_DPAD_LEFT -> MagnificationController.PAN_DIRECTION_LEFT; + case KeyEvent.KEYCODE_DPAD_RIGHT -> MagnificationController.PAN_DIRECTION_RIGHT; + case KeyEvent.KEYCODE_DPAD_UP -> MagnificationController.PAN_DIRECTION_UP; + default -> MagnificationController.PAN_DIRECTION_DOWN; + }; + if (isDown) { + mCallback.onPanMagnificationStart(getDisplayId(event), panDirection); + } else { + mCallback.onPanMagnificationStop(getDisplayId(event), panDirection); + } + return; + } else if (keyCode == KeyEvent.KEYCODE_EQUALS || keyCode == KeyEvent.KEYCODE_MINUS) { + int zoomDirection = MagnificationController.ZOOM_DIRECTION_OUT; + if (keyCode == KeyEvent.KEYCODE_EQUALS) { + zoomDirection = MagnificationController.ZOOM_DIRECTION_IN; + } + if (isDown) { + mCallback.onScaleMagnificationStart(getDisplayId(event), zoomDirection); + } else { + mCallback.onScaleMagnificationStop(getDisplayId(event), zoomDirection); + } + return; + } + + // Continue down the eventing chain if this was unused. + super.onKeyEvent(event, policyFlags); + } + + private int getDisplayId(KeyEvent event) { + // Display ID may be invalid, e.g. for external keyboard attached to phone. + // In that case, use the default display. + if (event.getDisplayId() != Display.INVALID_DISPLAY) { + return event.getDisplayId(); + } + return Display.DEFAULT_DISPLAY; + } +} diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java index 5af2346650ed..2143aaaa4cd6 100644 --- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java +++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java @@ -236,12 +236,13 @@ public class UserBackupManagerService { // If an app is busy when we want to do a full-data backup, how long to defer the retry. // This is fuzzed, so there are two parameters; backoff_min + Rand[0, backoff_fuzz) - private static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60; // one hour - private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2; // two hours + private static final long BUSY_BACKOFF_MIN_MILLIS = 1000 * 60 * 60; // one hour + private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2; // two hours private static final String SERIAL_ID_FILE = "serial_id"; private final @UserIdInt int mUserId; + private final String mLogIdMsg; // Prepended to Logcat messages. private final BackupAgentTimeoutParameters mAgentTimeoutParameters; private final TransportManager mTransportManager; @@ -259,13 +260,13 @@ public class UserBackupManagerService { private final IBackupManager mBackupManagerBinder; - private boolean mEnabled; // writes to this are synchronized on 'this' + private boolean mEnabled; // writes to this are synchronized on 'this' private boolean mSetupComplete; private boolean mAutoRestore; private final PendingIntent mRunInitIntent; - private final ArraySet<String> mPendingInits = new ArraySet<>(); // transport names + private final ArraySet<String> mPendingInits = new ArraySet<>(); // transport names // map UIDs to the set of participating packages under that UID private final SparseArray<HashSet<String>> mBackupParticipants = new SparseArray<>(); @@ -315,8 +316,7 @@ public class UserBackupManagerService { private final File mBaseStateDir; private final File mDataDir; private final File mJournalDir; - @Nullable - private DataChangedJournal mJournal; + @Nullable private DataChangedJournal mJournal; private final File mFullBackupScheduleFile; // Keep a log of all the apps we've ever backed up. @@ -337,7 +337,7 @@ public class UserBackupManagerService { * includes setting up the directories where we keep our bookkeeping and transport management. * * @see #createAndInitializeService(int, Context, BackupManagerService, HandlerThread, File, - * File, TransportManager) + * File, TransportManager) */ static UserBackupManagerService createAndInitializeService( @UserIdInt int userId, @@ -351,7 +351,7 @@ public class UserBackupManagerService { currentTransport = null; } - Slog.d(TAG, addUserIdToLogMessage(userId, "Starting with transport " + currentTransport)); + Slog.d(TAG, "Starting with transport " + currentTransport + " for user " + userId); TransportManager transportManager = new TransportManager(userId, context, transportWhitelist, currentTransport); @@ -361,7 +361,7 @@ public class UserBackupManagerService { HandlerThread userBackupThread = new HandlerThread("backup-" + userId, Process.THREAD_PRIORITY_BACKGROUND); userBackupThread.start(); - Slog.d(TAG, addUserIdToLogMessage(userId, "Started thread " + userBackupThread.getName())); + Slog.d(TAG, "Started thread " + userBackupThread.getName() + " for user " + userId); return createAndInitializeService( userId, @@ -417,26 +417,32 @@ public class UserBackupManagerService { */ public static boolean getSetupCompleteSettingForUser(Context context, int userId) { return Settings.Secure.getIntForUser( - context.getContentResolver(), - Settings.Secure.USER_SETUP_COMPLETE, - 0, - userId) + context.getContentResolver(), + Settings.Secure.USER_SETUP_COMPLETE, + 0, + userId) != 0; } @VisibleForTesting - UserBackupManagerService(Context context, PackageManager packageManager, - LifecycleOperationStorage operationStorage, TransportManager transportManager, - BackupHandler backupHandler, BackupManagerConstants backupManagerConstants, - IActivityManager activityManager, ActivityManagerInternal activityManagerInternal) { + UserBackupManagerService( + Context context, + PackageManager packageManager, + LifecycleOperationStorage operationStorage, + TransportManager transportManager, + BackupHandler backupHandler, + BackupManagerConstants backupManagerConstants, + IActivityManager activityManager, + ActivityManagerInternal activityManagerInternal) { mContext = context; mUserId = 0; + mLogIdMsg = "[UserID:" + mUserId + "] "; mRegisterTransportsRequestedTime = 0; mPackageManager = packageManager; mOperationStorage = operationStorage; - mBackupAgentConnectionManager = new BackupAgentConnectionManager(mOperationStorage, - mPackageManager, this, mUserId); + mBackupAgentConnectionManager = + new BackupAgentConnectionManager(mOperationStorage, mPackageManager, this, mUserId); mTransportManager = transportManager; mFullBackupQueue = new ArrayList<>(); mBackupHandler = backupHandler; @@ -470,13 +476,14 @@ public class UserBackupManagerService { File dataDir, TransportManager transportManager) { mUserId = userId; + mLogIdMsg = "[UserID:" + mUserId + "] "; mContext = Objects.requireNonNull(context, "context cannot be null"); mPackageManager = context.getPackageManager(); mPackageManagerBinder = AppGlobals.getPackageManager(); mActivityManager = ActivityManager.getService(); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); - mScheduledBackupEligibility = getEligibilityRules(mPackageManager, userId, mContext, - BackupDestination.CLOUD); + mScheduledBackupEligibility = + getEligibilityRules(mPackageManager, userId, mContext, BackupDestination.CLOUD); mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); @@ -484,13 +491,13 @@ public class UserBackupManagerService { Objects.requireNonNull(parent, "parent cannot be null"); mBackupManagerBinder = BackupManagerService.asInterface(parent.asBinder()); - mAgentTimeoutParameters = new - BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver()); + mAgentTimeoutParameters = + new BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver()); mAgentTimeoutParameters.start(); mOperationStorage = new LifecycleOperationStorage(mUserId); - mBackupAgentConnectionManager = new BackupAgentConnectionManager(mOperationStorage, - mPackageManager, this, mUserId); + mBackupAgentConnectionManager = + new BackupAgentConnectionManager(mOperationStorage, mPackageManager, this, mUserId); Objects.requireNonNull(userBackupThread, "userBackupThread cannot be null"); mBackupHandler = new BackupHandler(this, mOperationStorage, userBackupThread); @@ -498,8 +505,10 @@ public class UserBackupManagerService { // Set up our bookkeeping final ContentResolver resolver = context.getContentResolver(); mSetupComplete = getSetupCompleteSettingForUser(context, userId); - mAutoRestore = Settings.Secure.getIntForUser(resolver, - Settings.Secure.BACKUP_AUTO_RESTORE, 1, userId) != 0; + mAutoRestore = + Settings.Secure.getIntForUser( + resolver, Settings.Secure.BACKUP_AUTO_RESTORE, 1, userId) + != 0; mSetupObserver = new SetupObserver(this, mBackupHandler); resolver.registerContentObserver( @@ -514,10 +523,7 @@ public class UserBackupManagerService { if (userId == UserHandle.USER_SYSTEM) { mBaseStateDir.mkdirs(); if (!SELinux.restorecon(mBaseStateDir)) { - Slog.w( - TAG, - addUserIdToLogMessage( - userId, "SELinux restorecon failed on " + mBaseStateDir)); + Slog.w(TAG, mLogIdMsg + "SELinux restorecon failed on " + mBaseStateDir); } } @@ -549,8 +555,8 @@ public class UserBackupManagerService { // Set up the backup-request journaling mJournalDir = new File(mBaseStateDir, "pending"); - mJournalDir.mkdirs(); // creates mBaseStateDir along the way - mJournal = null; // will be created on first use + mJournalDir.mkdirs(); // creates mBaseStateDir along the way + mJournal = null; // will be created on first use mConstants = new BackupManagerConstants(mBackupHandler, mContext.getContentResolver()); // We are observing changes to the constants throughout the lifecycle of BMS. This is @@ -580,14 +586,20 @@ public class UserBackupManagerService { // if so delete expired events and do not print them to dumpsys BackupManagerMonitorDumpsysUtils backupManagerMonitorDumpsysUtils = new BackupManagerMonitorDumpsysUtils(); - mBackupHandler.postDelayed(backupManagerMonitorDumpsysUtils::deleteExpiredBMMEvents, + mBackupHandler.postDelayed( + backupManagerMonitorDumpsysUtils::deleteExpiredBMMEvents, INITIALIZATION_DELAY_MILLIS); mBackupPreferences = new UserBackupPreferences(mContext, mBaseStateDir); // Power management - mWakelock = new BackupWakeLock(mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "*backup*-" + userId + "-" + userBackupThread.getThreadId()), userId, mConstants); + mWakelock = + new BackupWakeLock( + mPowerManager.newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, + "*backup*-" + userId + "-" + userBackupThread.getThreadId()), + userId, + mConstants); // Set up the various sorts of package tracking we do mFullBackupScheduleFile = new File(mBaseStateDir, "fb-schedule"); @@ -788,14 +800,13 @@ public class UserBackupManagerService { mPendingInits.clear(); } - public void setRunningFullBackupTask( - PerformFullTransportBackupTask runningFullBackupTask) { + public void setRunningFullBackupTask(PerformFullTransportBackupTask runningFullBackupTask) { mRunningFullBackupTask = runningFullBackupTask; } /** - * Utility: build a new random integer token. The low bits are the ordinal of the operation for - * near-time uniqueness, and the upper bits are random for app-side unpredictability. + * Utility: build a new random integer token. The low bits are the ordinal of the operation for + * near-time uniqueness, and the upper bits are random for app-side unpredictability. */ public int generateRandomIntegerToken() { int token = mTokenGenerator.nextInt(); @@ -815,16 +826,14 @@ public class UserBackupManagerService { public BackupAgent makeMetadataAgentWithEligibilityRules( BackupEligibilityRules backupEligibilityRules) { - PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager, mUserId, - backupEligibilityRules); + PackageManagerBackupAgent pmAgent = + new PackageManagerBackupAgent(mPackageManager, mUserId, backupEligibilityRules); pmAgent.attach(mContext); pmAgent.onCreate(UserHandle.of(mUserId)); return pmAgent; } - /** - * Same as {@link #makeMetadataAgent()} but with explicit package-set configuration. - */ + /** Same as {@link #makeMetadataAgent()} but with explicit package-set configuration. */ public PackageManagerBackupAgent makeMetadataAgent(List<PackageInfo> packages) { PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager, packages, mUserId); @@ -834,12 +843,12 @@ public class UserBackupManagerService { } private void initPackageTracking() { - if (DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "` tracking")); + if (DEBUG) Slog.v(TAG, mLogIdMsg + "` tracking"); // Remember our ancestral dataset mTokenFile = new File(mBaseStateDir, "ancestral"); - try (DataInputStream tokenStream = new DataInputStream(new BufferedInputStream( - new FileInputStream(mTokenFile)))) { + try (DataInputStream tokenStream = + new DataInputStream(new BufferedInputStream(new FileInputStream(mTokenFile)))) { int version = tokenStream.readInt(); if (version == CURRENT_ANCESTRAL_RECORD_VERSION) { mAncestralToken = tokenStream.readLong(); @@ -856,9 +865,9 @@ public class UserBackupManagerService { } } catch (FileNotFoundException fnf) { // Probably innocuous - Slog.d(TAG, addUserIdToLogMessage(mUserId, "No ancestral data")); + Slog.d(TAG, mLogIdMsg + "No ancestral data"); } catch (IOException e) { - Slog.w(TAG, addUserIdToLogMessage(mUserId, "Unable to read token file"), e); + Slog.w(TAG, mLogIdMsg + "Unable to read token file", e); } mProcessedPackagesJournal = new ProcessedPackagesJournal(mBaseStateDir); @@ -899,20 +908,20 @@ public class UserBackupManagerService { boolean changed = false; ArrayList<FullBackupEntry> schedule = null; List<PackageInfo> apps = - PackageManagerBackupAgent.getStorableApplications(mPackageManager, mUserId, - mScheduledBackupEligibility); + PackageManagerBackupAgent.getStorableApplications( + mPackageManager, mUserId, mScheduledBackupEligibility); if (mFullBackupScheduleFile.exists()) { try (FileInputStream fstream = new FileInputStream(mFullBackupScheduleFile); - BufferedInputStream bufStream = new BufferedInputStream(fstream); - DataInputStream in = new DataInputStream(bufStream)) { + BufferedInputStream bufStream = new BufferedInputStream(fstream); + DataInputStream in = new DataInputStream(bufStream)) { int version = in.readInt(); if (version != SCHEDULE_FILE_VERSION) { // The file version doesn't match the expected value. // Since this is within a "try" block, this exception will be treated like // any other exception, and caught below. - throw new IllegalArgumentException("Unknown backup schedule version " - + version); + throw new IllegalArgumentException( + "Unknown backup schedule version " + version); } final int numPackages = in.readInt(); @@ -935,12 +944,20 @@ public class UserBackupManagerService { pkg.applicationInfo)) { schedule.add(new FullBackupEntry(pkgName, lastBackup)); } else { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Package " + pkgName - + " no longer eligible for full backup")); + Slog.i( + TAG, + mLogIdMsg + + "Package " + + pkgName + + " no longer eligible for full backup"); } } catch (NameNotFoundException e) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Package " + pkgName - + " not installed; dropping from full backup")); + Slog.i( + TAG, + mLogIdMsg + + "Package " + + pkgName + + " not installed; dropping from full backup"); } } @@ -954,11 +971,10 @@ public class UserBackupManagerService { if (DEBUG) { Slog.i( TAG, - addUserIdToLogMessage( - mUserId, - "New full backup app " - + app.packageName - + " found")); + mLogIdMsg + + "New full backup app " + + app.packageName + + " found"); } schedule.add(new FullBackupEntry(app.packageName, 0)); changed = true; @@ -968,7 +984,7 @@ public class UserBackupManagerService { Collections.sort(schedule); } catch (Exception e) { - Slog.e(TAG, addUserIdToLogMessage(mUserId, "Unable to read backup schedule"), e); + Slog.e(TAG, mLogIdMsg + "Unable to read backup schedule", e); mFullBackupScheduleFile.delete(); schedule = null; } @@ -994,46 +1010,43 @@ public class UserBackupManagerService { return schedule; } - private Runnable mFullBackupScheduleWriter = new Runnable() { - @Override - public void run() { - synchronized (mQueueLock) { - try { - ByteArrayOutputStream bufStream = new ByteArrayOutputStream(4096); - DataOutputStream bufOut = new DataOutputStream(bufStream); - bufOut.writeInt(SCHEDULE_FILE_VERSION); - - // version 1: - // - // [int] # of packages in the queue = N - // N * { - // [utf8] package name - // [long] last backup time for this package - // } - int numPackages = mFullBackupQueue.size(); - bufOut.writeInt(numPackages); - - for (int i = 0; i < numPackages; i++) { - FullBackupEntry entry = mFullBackupQueue.get(i); - bufOut.writeUTF(entry.packageName); - bufOut.writeLong(entry.lastBackup); + private Runnable mFullBackupScheduleWriter = + new Runnable() { + @Override + public void run() { + synchronized (mQueueLock) { + try { + ByteArrayOutputStream bufStream = new ByteArrayOutputStream(4096); + DataOutputStream bufOut = new DataOutputStream(bufStream); + bufOut.writeInt(SCHEDULE_FILE_VERSION); + + // version 1: + // + // [int] # of packages in the queue = N + // N * { + // [utf8] package name + // [long] last backup time for this package + // } + int numPackages = mFullBackupQueue.size(); + bufOut.writeInt(numPackages); + + for (int i = 0; i < numPackages; i++) { + FullBackupEntry entry = mFullBackupQueue.get(i); + bufOut.writeUTF(entry.packageName); + bufOut.writeLong(entry.lastBackup); + } + bufOut.flush(); + + AtomicFile af = new AtomicFile(mFullBackupScheduleFile); + FileOutputStream out = af.startWrite(); + out.write(bufStream.toByteArray()); + af.finishWrite(out); + } catch (Exception e) { + Slog.e(TAG, mLogIdMsg + "Unable to write backup schedule!", e); + } } - bufOut.flush(); - - AtomicFile af = new AtomicFile(mFullBackupScheduleFile); - FileOutputStream out = af.startWrite(); - out.write(bufStream.toByteArray()); - af.finishWrite(out); - } catch (Exception e) { - Slog.e( - TAG, - addUserIdToLogMessage( - mUserId, "Unable to write backup schedule!"), - e); } - } - } - }; + }; private void writeFullBackupScheduleAsync() { mBackupHandler.removeCallbacks(mFullBackupScheduleWriter); @@ -1044,28 +1057,33 @@ public class UserBackupManagerService { ArrayList<DataChangedJournal> journals = DataChangedJournal.listJournals(mJournalDir); journals.removeAll(Collections.singletonList(mJournal)); if (!journals.isEmpty()) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, - "Found " + journals.size() + " stale backup journal(s), scheduling.")); + Slog.i( + TAG, + mLogIdMsg + + "Found " + + journals.size() + + " stale backup journal(s), scheduling."); } Set<String> packageNames = new LinkedHashSet<>(); for (DataChangedJournal journal : journals) { try { - journal.forEach(packageName -> { - if (packageNames.add(packageName)) { - dataChangedImpl(packageName); - } - }); + journal.forEach( + packageName -> { + if (packageNames.add(packageName)) { + dataChangedImpl(packageName); + } + }); } catch (IOException e) { - Slog.e(TAG, addUserIdToLogMessage(mUserId, "Can't read " + journal), e); + Slog.e(TAG, mLogIdMsg + "Can't read " + journal, e); } } if (!packageNames.isEmpty()) { - String msg = "Stale backup journals: Scheduled " + packageNames.size() - + " package(s) total"; + String msg = + "Stale backup journals: Scheduled " + packageNames.size() + " package(s) total"; if (DEBUG) { msg += ": " + packageNames; } - Slog.i(TAG, addUserIdToLogMessage(mUserId, msg)); + Slog.i(TAG, mLogIdMsg + msg); } } @@ -1105,12 +1123,11 @@ public class UserBackupManagerService { if (DEBUG) { Slog.i( TAG, - addUserIdToLogMessage( - mUserId, - "recordInitPending(" - + isPending - + ") on transport " - + transportName)); + mLogIdMsg + + "recordInitPending(" + + isPending + + ") on transport " + + transportName); } File stateDir = new File(mBaseStateDir, transportDirName); @@ -1170,10 +1187,16 @@ public class UserBackupManagerService { private void onTransportRegistered(String transportName, String transportDirName) { long timeMs = SystemClock.elapsedRealtime() - mRegisterTransportsRequestedTime; - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "Transport " + transportName + " registered " + timeMs - + "ms after first request (delay = " + INITIALIZATION_DELAY_MILLIS - + "ms)")); + Slog.d( + TAG, + mLogIdMsg + + "Transport " + + transportName + + " registered " + + timeMs + + "ms after first request (delay = " + + INITIALIZATION_DELAY_MILLIS + + "ms)"); File stateDir = new File(mBaseStateDir, transportDirName); stateDir.mkdirs(); @@ -1185,8 +1208,10 @@ public class UserBackupManagerService { // TODO: pick a better starting time than now + 1 minute long delay = 1000 * 60; // one minute, in milliseconds - mAlarmManager.set(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + delay, mRunInitIntent); + mAlarmManager.set( + AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + delay, + mRunInitIntent); } } } @@ -1195,137 +1220,131 @@ public class UserBackupManagerService { * A {@link BroadcastReceiver} tracking changes to packages and sd cards in order to update our * internal bookkeeping. */ - private BroadcastReceiver mPackageTrackingReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - if (DEBUG) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Received broadcast " + intent)); - } + private BroadcastReceiver mPackageTrackingReceiver = + new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + if (DEBUG) { + Slog.d(TAG, mLogIdMsg + "Received broadcast " + intent); + } - String action = intent.getAction(); - boolean replacing = false; - boolean added = false; - boolean changed = false; - Bundle extras = intent.getExtras(); - String[] packageList = null; + String action = intent.getAction(); + boolean replacing = false; + boolean added = false; + boolean changed = false; + Bundle extras = intent.getExtras(); + String[] packageList = null; + + if (Intent.ACTION_PACKAGE_ADDED.equals(action) + || Intent.ACTION_PACKAGE_REMOVED.equals(action) + || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { + Uri uri = intent.getData(); + if (uri == null) { + return; + } - if (Intent.ACTION_PACKAGE_ADDED.equals(action) - || Intent.ACTION_PACKAGE_REMOVED.equals(action) - || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { - Uri uri = intent.getData(); - if (uri == null) { - return; - } + String packageName = uri.getSchemeSpecificPart(); + if (packageName != null) { + packageList = new String[] {packageName}; + } - String packageName = uri.getSchemeSpecificPart(); - if (packageName != null) { - packageList = new String[] {packageName}; - } + changed = Intent.ACTION_PACKAGE_CHANGED.equals(action); + if (changed) { + // Look at new transport states for package changed events. + String[] components = + intent.getStringArrayExtra( + Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); - changed = Intent.ACTION_PACKAGE_CHANGED.equals(action); - if (changed) { - // Look at new transport states for package changed events. - String[] components = - intent.getStringArrayExtra( - Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); + if (DEBUG) { + Slog.i(TAG, mLogIdMsg + "Package " + packageName + " changed"); + for (int i = 0; i < components.length; i++) { + Slog.i(TAG, mLogIdMsg + " * " + components[i]); + } + } - if (DEBUG) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, "Package " + packageName + " changed")); - for (int i = 0; i < components.length; i++) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, " * " + components[i])); + mBackupHandler.post( + () -> + mTransportManager.onPackageChanged( + packageName, components)); + return; } - } - mBackupHandler.post( - () -> - mTransportManager.onPackageChanged( - packageName, components)); - return; - } + added = Intent.ACTION_PACKAGE_ADDED.equals(action); + replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); + } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { + added = true; + packageList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); + } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { + added = false; + packageList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); + } - added = Intent.ACTION_PACKAGE_ADDED.equals(action); - replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false); - } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { - added = true; - packageList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); - } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { - added = false; - packageList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); - } + if (packageList == null || packageList.length == 0) { + return; + } - if (packageList == null || packageList.length == 0) { - return; - } + int uid = extras.getInt(Intent.EXTRA_UID); + if (added) { + synchronized (mBackupParticipants) { + if (replacing) { + // Remove the entry under the old uid and fall through to re-add. If + // an app + // just opted into key/value backup, add it as a known participant. + removePackageParticipantsLocked(packageList, uid); + } + addPackageParticipantsLocked(packageList); + } - int uid = extras.getInt(Intent.EXTRA_UID); - if (added) { - synchronized (mBackupParticipants) { - if (replacing) { - // Remove the entry under the old uid and fall through to re-add. If - // an app - // just opted into key/value backup, add it as a known participant. - removePackageParticipantsLocked(packageList, uid); - } - addPackageParticipantsLocked(packageList); - } + long now = System.currentTimeMillis(); + for (String packageName : packageList) { + try { + PackageInfo app = + mPackageManager.getPackageInfoAsUser( + packageName, /* flags */ 0, mUserId); + if (mScheduledBackupEligibility.appGetsFullBackup(app) + && mScheduledBackupEligibility.appIsEligibleForBackup( + app.applicationInfo)) { + enqueueFullBackup(packageName, now); + scheduleNextFullBackupJob(0); + } else { + // The app might have just transitioned out of full-data into + // doing + // key/value backups, or might have just disabled backups + // entirely. Make + // sure it is no longer in the full-data queue. + synchronized (mQueueLock) { + dequeueFullBackupLocked(packageName); + } + writeFullBackupScheduleAsync(); + } - long now = System.currentTimeMillis(); - for (String packageName : packageList) { - try { - PackageInfo app = - mPackageManager.getPackageInfoAsUser( - packageName, /* flags */ 0, mUserId); - if (mScheduledBackupEligibility.appGetsFullBackup(app) - && mScheduledBackupEligibility.appIsEligibleForBackup( - app.applicationInfo)) { - enqueueFullBackup(packageName, now); - scheduleNextFullBackupJob(0); - } else { - // The app might have just transitioned out of full-data into - // doing - // key/value backups, or might have just disabled backups - // entirely. Make - // sure it is no longer in the full-data queue. - synchronized (mQueueLock) { - dequeueFullBackupLocked(packageName); + mBackupHandler.post( + () -> mTransportManager.onPackageAdded(packageName)); + } catch (NameNotFoundException e) { + Slog.w(TAG, mLogIdMsg + "Can't resolve new app " + packageName); } - writeFullBackupScheduleAsync(); } - mBackupHandler.post( - () -> mTransportManager.onPackageAdded(packageName)); - } catch (NameNotFoundException e) { - Slog.w(TAG, addUserIdToLogMessage(mUserId, - "Can't resolve new app " + packageName)); - } - } + // Whenever a package is added or updated we need to update the package + // metadata + // bookkeeping. + dataChangedImpl(PACKAGE_MANAGER_SENTINEL); + } else { + if (!replacing) { + // Outright removal. In the full-data case, the app will be dropped from + // the + // queue when its (now obsolete) name comes up again for backup. + synchronized (mBackupParticipants) { + removePackageParticipantsLocked(packageList, uid); + } + } - // Whenever a package is added or updated we need to update the package - // metadata - // bookkeeping. - dataChangedImpl(PACKAGE_MANAGER_SENTINEL); - } else { - if (!replacing) { - // Outright removal. In the full-data case, the app will be dropped from - // the - // queue when its (now obsolete) name comes up again for backup. - synchronized (mBackupParticipants) { - removePackageParticipantsLocked(packageList, uid); + for (String packageName : packageList) { + mBackupHandler.post( + () -> mTransportManager.onPackageRemoved(packageName)); + } } } - - for (String packageName : packageList) { - mBackupHandler.post( - () -> mTransportManager.onPackageRemoved(packageName)); - } - } - } - }; + }; // Add the backup agents in the given packages to our set of known backup participants. // If 'packageNames' is null, adds all backup agents in the whole system. @@ -1334,29 +1353,23 @@ public class UserBackupManagerService { List<PackageInfo> targetApps = allAgentPackages(); if (packageNames != null) { if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, "addPackageParticipantsLocked: #" + packageNames.length)); + Slog.v(TAG, mLogIdMsg + "addPackageParticipantsLocked: #" + packageNames.length); } for (String packageName : packageNames) { addPackageParticipantsLockedInner(packageName, targetApps); } } else { if (DEBUG) { - Slog.v(TAG, addUserIdToLogMessage(mUserId, "addPackageParticipantsLocked: all")); + Slog.v(TAG, mLogIdMsg + "addPackageParticipantsLocked: all"); } addPackageParticipantsLockedInner(null, targetApps); } } - private void addPackageParticipantsLockedInner(String packageName, - List<PackageInfo> targetPkgs) { + private void addPackageParticipantsLockedInner( + String packageName, List<PackageInfo> targetPkgs) { if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, "Examining " + packageName + " for backup agent")); + Slog.v(TAG, mLogIdMsg + "Examining " + packageName + " for backup agent"); } for (PackageInfo pkg : targetPkgs) { @@ -1368,17 +1381,14 @@ public class UserBackupManagerService { mBackupParticipants.put(uid, set); } set.add(pkg.packageName); - if (DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, "Agent found; added")); + if (DEBUG) Slog.v(TAG, mLogIdMsg + "Agent found; added"); // Schedule a backup for it on general principles if (DEBUG) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, "Scheduling backup for new app " + pkg.packageName)); + Slog.i(TAG, mLogIdMsg + "Scheduling backup for new app " + pkg.packageName); } - Message msg = mBackupHandler - .obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName); + Message msg = + mBackupHandler.obtainMessage(MSG_SCHEDULE_BACKUP_PACKAGE, pkg.packageName); mBackupHandler.sendMessage(msg); } } @@ -1387,19 +1397,18 @@ public class UserBackupManagerService { // Remove the given packages' entries from our known active set. private void removePackageParticipantsLocked(String[] packageNames, int oldUid) { if (packageNames == null) { - Slog.w(TAG, addUserIdToLogMessage(mUserId, "removePackageParticipants with null list")); + Slog.w(TAG, mLogIdMsg + "removePackageParticipants with null list"); return; } if (DEBUG) { Slog.v( TAG, - addUserIdToLogMessage( - mUserId, - "removePackageParticipantsLocked: uid=" - + oldUid - + " #" - + packageNames.length)); + mLogIdMsg + + "removePackageParticipantsLocked: uid=" + + oldUid + + " #" + + packageNames.length); } for (String pkg : packageNames) { // Known previous UID, so we know which package set to check @@ -1408,10 +1417,7 @@ public class UserBackupManagerService { removePackageFromSetLocked(set, pkg); if (set.isEmpty()) { if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, " last one of this uid; purging set")); + Slog.v(TAG, mLogIdMsg + " last one of this uid; purging set"); } mBackupParticipants.remove(oldUid); } @@ -1419,8 +1425,7 @@ public class UserBackupManagerService { } } - private void removePackageFromSetLocked(final HashSet<String> set, - final String packageName) { + private void removePackageFromSetLocked(final HashSet<String> set, final String packageName) { if (set.contains(packageName)) { // Found it. Remove this one package from the bookkeeping, and // if it's the last participating app under this uid we drop the @@ -1429,9 +1434,7 @@ public class UserBackupManagerService { // bookkeeping so that its current-dataset data will be retrieved // if the app is subsequently reinstalled if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage(mUserId, " removing participant " + packageName)); + Slog.v(TAG, mLogIdMsg + " removing participant " + packageName); } set.remove(packageName); mPendingBackups.remove(packageName); @@ -1456,8 +1459,11 @@ public class UserBackupManagerService { // we will need the shared library path, so look that up and store it here. // This is used implicitly when we pass the PackageInfo object off to // the Activity Manager to launch the app for backup/restore purposes. - app = mPackageManager.getApplicationInfoAsUser(pkg.packageName, - PackageManager.GET_SHARED_LIBRARY_FILES, mUserId); + app = + mPackageManager.getApplicationInfoAsUser( + pkg.packageName, + PackageManager.GET_SHARED_LIBRARY_FILES, + mUserId); pkg.applicationInfo.sharedLibraryFiles = app.sharedLibraryFiles; pkg.applicationInfo.sharedLibraryInfos = app.sharedLibraryInfos; } @@ -1479,8 +1485,8 @@ public class UserBackupManagerService { final Intent notification = new Intent(); notification.setAction(BACKUP_FINISHED_ACTION); notification.setPackage(receiver); - notification.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES - | Intent.FLAG_RECEIVER_FOREGROUND); + notification.addFlags( + Intent.FLAG_INCLUDE_STOPPED_PACKAGES | Intent.FLAG_RECEIVER_FOREGROUND); notification.putExtra(BACKUP_FINISHED_PACKAGE_EXTRA, packageName); mContext.sendBroadcastAsUser(notification, UserHandle.of(mUserId)); } @@ -1506,17 +1512,14 @@ public class UserBackupManagerService { af.writeInt(-1); } else { af.writeInt(mAncestralPackages.size()); - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "Ancestral packages: " + mAncestralPackages.size())); + Slog.d(TAG, mLogIdMsg + "Ancestral packages: " + mAncestralPackages.size()); for (String pkgName : mAncestralPackages) { af.writeUTF(pkgName); - if (DEBUG) Slog.v(TAG, addUserIdToLogMessage(mUserId, " " + pkgName)); + if (DEBUG) Slog.v(TAG, mLogIdMsg + " " + pkgName); } } } catch (IOException e) { - Slog.w(TAG, addUserIdToLogMessage(mUserId, "Unable to write token file:"), e); + Slog.w(TAG, mLogIdMsg + "Unable to write token file:", e); } } @@ -1539,45 +1542,39 @@ public class UserBackupManagerService { /** * Clear an application's data, blocking until the operation completes or times out. * - * @param checkFlagAllowClearUserDataOnFailedRestore if {@code true} uses - * {@link ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE} to decide if - * clearing data is allowed after a failed restore. - * + * @param checkFlagAllowClearUserDataOnFailedRestore if {@code true} uses {@link + * ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE} to decide if + * clearing data is allowed after a failed restore. * @param keepSystemState if {@code true}, we don't clear system state such as already restored - * notification settings, permission grants, etc. + * notification settings, permission grants, etc. */ - private void clearApplicationDataSynchronous(String packageName, - boolean checkFlagAllowClearUserDataOnFailedRestore, boolean keepSystemState) { + private void clearApplicationDataSynchronous( + String packageName, + boolean checkFlagAllowClearUserDataOnFailedRestore, + boolean keepSystemState) { try { - ApplicationInfo applicationInfo = mPackageManager.getPackageInfoAsUser( - packageName, 0, mUserId).applicationInfo; + ApplicationInfo applicationInfo = + mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId).applicationInfo; boolean shouldClearData; if (checkFlagAllowClearUserDataOnFailedRestore && applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) { - shouldClearData = (applicationInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE) != 0; + int clearOnFailedRestoreFlag = + ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE; + shouldClearData = (applicationInfo.privateFlags & clearOnFailedRestoreFlag) != 0; } else { shouldClearData = - (applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) != 0; + (applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) != 0; } if (!shouldClearData) { if (DEBUG) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, - "Clearing app data is not allowed so not wiping " - + packageName)); + Slog.i(TAG, mLogIdMsg + "Clearing app data is not allowed " + packageName); } return; } } catch (NameNotFoundException e) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Tried to clear data for " + packageName + " but not found")); + Slog.w(TAG, mLogIdMsg + "Tried to clear data for " + packageName + " but not found"); return; } @@ -1585,8 +1582,8 @@ public class UserBackupManagerService { synchronized (mClearDataLock) { mClearingData = true; - mActivityManagerInternal.clearApplicationUserData(packageName, keepSystemState, - /*isRestore=*/ true, observer, mUserId); + mActivityManagerInternal.clearApplicationUserData( + packageName, keepSystemState, /* isRestore= */ true, observer, mUserId); // Only wait 30 seconds for the clear data to happen. long timeoutMark = System.currentTimeMillis() + CLEAR_DATA_TIMEOUT_INTERVAL; @@ -1598,20 +1595,16 @@ public class UserBackupManagerService { mClearingData = false; Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "Interrupted while waiting for " - + packageName - + " data to be cleared"), + mLogIdMsg + + "Interrupted while waiting for " + + packageName + + " data to be cleared", e); } } if (mClearingData) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Clearing app data for " + packageName + " timed out")); + Slog.w(TAG, mLogIdMsg + "Clearing app data for " + packageName + " timed out"); } } } @@ -1632,23 +1625,20 @@ public class UserBackupManagerService { * the active set if possible, else the ancestral one. Returns zero if none available. */ public long getAvailableRestoreToken(String packageName) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "getAvailableRestoreToken"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "getAvailableRestoreToken"); long token = mAncestralToken; synchronized (mQueueLock) { if (mCurrentToken != 0 && mProcessedPackagesJournal.hasBeenProcessed(packageName)) { if (DEBUG) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, "App in ever-stored, so using current token")); + Slog.i(TAG, mLogIdMsg + "App in ever-stored, so using current token"); } token = mCurrentToken; } } if (DEBUG) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "getAvailableRestoreToken() == " + token)); + Slog.i(TAG, mLogIdMsg + "getAvailableRestoreToken() == " + token); } return token; } @@ -1666,35 +1656,40 @@ public class UserBackupManagerService { * Requests a backup for the inputted {@code packages} with a specified {@link * IBackupManagerMonitor} and {@link OperationType}. */ - public int requestBackup(String[] packages, IBackupObserver observer, - IBackupManagerMonitor monitor, int flags) { - BackupManagerMonitorEventSender mBackupManagerMonitorEventSender = + public int requestBackup( + String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor, int flags) { + BackupManagerMonitorEventSender mBackupManagerMonitorEventSender = getBMMEventSender(monitor); mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup"); if (packages == null || packages.length < 1) { - Slog.e(TAG, addUserIdToLogMessage(mUserId, "No packages named for backup request")); + Slog.e(TAG, mLogIdMsg + "No packages named for backup request"); BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED); mBackupManagerMonitorEventSender.monitorEvent( - BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES, - null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null); + BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES, null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null); throw new IllegalArgumentException("No packages are provided for backup"); } if (!mEnabled || !mSetupComplete) { Slog.i( TAG, - addUserIdToLogMessage(mUserId, "Backup requested but enabled=" + mLogIdMsg + + "Backup requested but enabled=" + mEnabled + " setupComplete=" - + mSetupComplete)); - BackupObserverUtils.sendBackupFinished(observer, - BackupManager.ERROR_BACKUP_NOT_ALLOWED); - final int logTag = mSetupComplete - ? BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED - : BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED; - mBackupManagerMonitorEventSender.monitorEvent(logTag, null, - BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, null); + + mSetupComplete); + BackupObserverUtils.sendBackupFinished( + observer, BackupManager.ERROR_BACKUP_NOT_ALLOWED); + final int logTag = + mSetupComplete + ? BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED + : BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED; + mBackupManagerMonitorEventSender.monitorEvent( + logTag, + null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, + null); return BackupManager.ERROR_BACKUP_NOT_ALLOWED; } @@ -1708,31 +1703,45 @@ public class UserBackupManagerService { transportConnection = mTransportManager.getCurrentTransportClientOrThrow("BMS.requestBackup()"); backupDestination = getBackupDestinationFromTransport(transportConnection); - } catch (TransportNotRegisteredException | TransportNotAvailableException + } catch (TransportNotRegisteredException + | TransportNotAvailableException | RemoteException e) { BackupObserverUtils.sendBackupFinished(observer, BackupManager.ERROR_TRANSPORT_ABORTED); mBackupManagerMonitorEventSender.monitorEvent( - BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL, - null, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null); + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL, null, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null); return BackupManager.ERROR_TRANSPORT_ABORTED; } OnTaskFinishedListener listener = caller -> mTransportManager.disposeOfTransportClient(transportConnection, caller); - BackupEligibilityRules backupEligibilityRules = getEligibilityRulesForOperation( - backupDestination); + BackupEligibilityRules backupEligibilityRules = + getEligibilityRulesForOperation(backupDestination); Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP); - msg.obj = getRequestBackupParams(packages, observer, monitor, flags, backupEligibilityRules, - transportConnection, transportDirName, listener); + msg.obj = + getRequestBackupParams( + packages, + observer, + monitor, + flags, + backupEligibilityRules, + transportConnection, + transportDirName, + listener); mBackupHandler.sendMessage(msg); return BackupManager.SUCCESS; } @VisibleForTesting - BackupParams getRequestBackupParams(String[] packages, IBackupObserver observer, - IBackupManagerMonitor monitor, int flags, BackupEligibilityRules backupEligibilityRules, - TransportConnection transportConnection, String transportDirName, + BackupParams getRequestBackupParams( + String[] packages, + IBackupObserver observer, + IBackupManagerMonitor monitor, + int flags, + BackupEligibilityRules backupEligibilityRules, + TransportConnection transportConnection, + String transportDirName, OnTaskFinishedListener listener) { ArrayList<String> fullBackupList = new ArrayList<>(); ArrayList<String> kvBackupList = new ArrayList<>(); @@ -1742,11 +1751,12 @@ public class UserBackupManagerService { continue; } try { - PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageName, - PackageManager.GET_SIGNING_CERTIFICATES, mUserId); + PackageInfo packageInfo = + mPackageManager.getPackageInfoAsUser( + packageName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); if (!backupEligibilityRules.appIsEligibleForBackup(packageInfo.applicationInfo)) { - BackupObserverUtils.sendBackupOnPackageResult(observer, packageName, - BackupManager.ERROR_BACKUP_NOT_ALLOWED); + BackupObserverUtils.sendBackupOnPackageResult( + observer, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED); continue; } if (backupEligibilityRules.appGetsFullBackup(packageInfo)) { @@ -1755,31 +1765,41 @@ public class UserBackupManagerService { kvBackupList.add(packageInfo.packageName); } } catch (NameNotFoundException e) { - BackupObserverUtils.sendBackupOnPackageResult(observer, packageName, - BackupManager.ERROR_PACKAGE_NOT_FOUND); + BackupObserverUtils.sendBackupOnPackageResult( + observer, packageName, BackupManager.ERROR_PACKAGE_NOT_FOUND); } } - EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(), + EventLog.writeEvent( + EventLogTags.BACKUP_REQUESTED, + packages.length, + kvBackupList.size(), fullBackupList.size()); if (DEBUG) { Slog.i( TAG, - addUserIdToLogMessage( - mUserId, - "Backup requested for " - + packages.length - + " packages, of them: " - + fullBackupList.size() - + " full backups, " - + kvBackupList.size() - + " k/v backups")); + mLogIdMsg + + "Backup requested for " + + packages.length + + " packages, of them: " + + fullBackupList.size() + + " full backups, " + + kvBackupList.size() + + " k/v backups"); } boolean nonIncrementalBackup = (flags & BackupManager.FLAG_NON_INCREMENTAL_BACKUP) != 0; - return new BackupParams(transportConnection, transportDirName, kvBackupList, fullBackupList, - observer, monitor, listener, /* userInitiated */ true, nonIncrementalBackup, + return new BackupParams( + transportConnection, + transportDirName, + kvBackupList, + fullBackupList, + observer, + monitor, + listener, /* userInitiated */ + true, + nonIncrementalBackup, backupEligibilityRules); } @@ -1787,7 +1807,7 @@ public class UserBackupManagerService { public void cancelBackups() { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups"); if (DEBUG) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "cancelBackups() called.")); + Slog.i(TAG, mLogIdMsg + "cancelBackups() called."); } final long oldToken = Binder.clearCallingIdentity(); try { @@ -1795,14 +1815,24 @@ public class UserBackupManagerService { mOperationStorage.operationTokensForOpType(OpType.BACKUP); for (Integer token : operationsToCancel) { - mOperationStorage.cancelOperation(token, /* cancelAll */ true, - operationType -> { /* no callback needed here */ }); + mOperationStorage.cancelOperation( + token, /* cancelAll */ + true, + operationType -> { + /* no callback needed here */ + }); } // We don't want the backup jobs to kick in any time soon. // Reschedules them to run in the distant future. - KeyValueBackupJob.schedule(mUserId, mContext, BUSY_BACKOFF_MIN_MILLIS, + KeyValueBackupJob.schedule( + mUserId, + mContext, + BUSY_BACKOFF_MIN_MILLIS, /* userBackupManagerService */ this); - FullBackupJob.schedule(mUserId, mContext, 2 * BUSY_BACKOFF_MIN_MILLIS, + FullBackupJob.schedule( + mUserId, + mContext, + 2 * BUSY_BACKOFF_MIN_MILLIS, /* userBackupManagerService */ this); } finally { Binder.restoreCallingIdentity(oldToken); @@ -1810,35 +1840,34 @@ public class UserBackupManagerService { } /** Schedule a timeout message for the operation identified by {@code token}. */ - public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback, - int operationType) { + public void prepareOperationTimeout( + int token, long interval, BackupRestoreTask callback, int operationType) { if (operationType != OpType.BACKUP_WAIT && operationType != OpType.RESTORE_WAIT) { Slog.wtf( TAG, - addUserIdToLogMessage( - mUserId, - "prepareOperationTimeout() doesn't support operation " - + Integer.toHexString(token) - + " of type " - + operationType)); + mLogIdMsg + + "prepareOperationTimeout() doesn't support operation " + + Integer.toHexString(token) + + " of type " + + operationType); return; } if (DEBUG) { Slog.v( TAG, - addUserIdToLogMessage( - mUserId, - "starting timeout: token=" - + Integer.toHexString(token) - + " interval=" - + interval - + " callback=" - + callback)); + mLogIdMsg + + "starting timeout: token=" + + Integer.toHexString(token) + + " interval=" + + interval + + " callback=" + + callback); } mOperationStorage.registerOperation(token, OpState.PENDING, callback, operationType); - Message msg = mBackupHandler.obtainMessage(getMessageIdForOperationType(operationType), - token, 0, callback); + Message msg = + mBackupHandler.obtainMessage( + getMessageIdForOperationType(operationType), token, 0, callback); mBackupHandler.sendMessageDelayed(msg, interval); } @@ -1851,19 +1880,20 @@ public class UserBackupManagerService { default: Slog.wtf( TAG, - addUserIdToLogMessage( - mUserId, - "getMessageIdForOperationType called on invalid operation type: " - + operationType)); + mLogIdMsg + + "getMessageIdForOperationType called on invalid operation type: " + + operationType); return -1; } } /** Block until we received an operation complete message (from the agent or cancellation). */ public boolean waitUntilOperationComplete(int token) { - return mOperationStorage.waitUntilOperationComplete(token, operationType -> { - mBackupHandler.removeMessages(getMessageIdForOperationType(operationType)); - }); + return mOperationStorage.waitUntilOperationComplete( + token, + operationType -> { + mBackupHandler.removeMessages(getMessageIdForOperationType(operationType)); + }); } /** Cancel the operation associated with {@code token}. */ @@ -1871,11 +1901,15 @@ public class UserBackupManagerService { // Remove all pending timeout messages of types OpType.BACKUP_WAIT and // OpType.RESTORE_WAIT. On the other hand, OP_TYPE_BACKUP cannot time out and // doesn't require cancellation. - mOperationStorage.cancelOperation(token, cancelAll, operationType -> { - if (operationType == OpType.BACKUP_WAIT || operationType == OpType.RESTORE_WAIT) { - mBackupHandler.removeMessages(getMessageIdForOperationType(operationType)); - } - }); + mOperationStorage.cancelOperation( + token, + cancelAll, + operationType -> { + if (operationType == OpType.BACKUP_WAIT + || operationType == OpType.RESTORE_WAIT) { + mBackupHandler.removeMessages(getMessageIdForOperationType(operationType)); + } + }); } /** Returns {@code true} if a backup is currently running, else returns {@code false}. */ @@ -1885,9 +1919,7 @@ public class UserBackupManagerService { // ----- Full-data backup scheduling ----- - /** - * Schedule a job to tell us when it's a good time to run a full backup - */ + /** Schedule a job to tell us when it's a good time to run a full backup */ public void scheduleNextFullBackupJob(long transportMinLatency) { synchronized (mQueueLock) { if (mFullBackupQueue.size() > 0) { @@ -1899,18 +1931,15 @@ public class UserBackupManagerService { final long interval = mConstants.getFullBackupIntervalMilliseconds(); final long appLatency = (timeSinceLast < interval) ? (interval - timeSinceLast) : 0; final long latency = Math.max(transportMinLatency, appLatency); - FullBackupJob.schedule(mUserId, mContext, latency, - /* userBackupManagerService */ this); + FullBackupJob.schedule( + mUserId, mContext, latency, /* userBackupManagerService */ this); } else { - Slog.i(TAG, - addUserIdToLogMessage(mUserId, "Full backup queue empty; not scheduling")); + Slog.i(TAG, mLogIdMsg + "Full backup queue empty; not scheduling"); } } } - /** - * Remove a package from the full-data queue. - */ + /** Remove a package from the full-data queue. */ @GuardedBy("mQueueLock") private void dequeueFullBackupLocked(String packageName) { final int numPackages = mFullBackupQueue.size(); @@ -1922,9 +1951,7 @@ public class UserBackupManagerService { } } - /** - * Enqueue full backup for the given app, with a note about when it last ran. - */ + /** Enqueue full backup for the given app, with a note about when it last ran. */ public void enqueueFullBackup(String packageName, long lastBackedUp) { FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp); synchronized (mQueueLock) { @@ -1957,10 +1984,7 @@ public class UserBackupManagerService { private boolean fullBackupAllowable(String transportName) { if (!mTransportManager.isTransportRegistered(transportName)) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Transport not registered; full data backup not performed")); + Slog.w(TAG, mLogIdMsg + "Transport not registered; full data backup not performed"); return false; } @@ -1971,15 +1995,11 @@ public class UserBackupManagerService { File stateDir = new File(mBaseStateDir, transportDirName); File pmState = new File(stateDir, PACKAGE_MANAGER_SENTINEL); if (pmState.length() <= 0) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, - "Full backup requested but dataset not yet initialized")); + Slog.i(TAG, mLogIdMsg + "Full backup requested but dataset not yet initialized"); return false; } } catch (Exception e) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Unable to get transport name: " + e.getMessage())); + Slog.w(TAG, mLogIdMsg + "Unable to get transport name: " + e.getMessage()); return false; } @@ -1987,14 +2007,14 @@ public class UserBackupManagerService { } /** - * Conditions are right for a full backup operation, so run one. The model we use is - * to perform one app backup per scheduled job execution, and to reschedule the job - * with zero latency as long as conditions remain right and we still have work to do. + * Conditions are right for a full backup operation, so run one. The model we use is to perform + * one app backup per scheduled job execution, and to reschedule the job with zero latency as + * long as conditions remain right and we still have work to do. * * <p>This is the "start a full backup operation" entry point called by the scheduled job. * - * @return Whether ongoing work will continue. The return value here will be passed - * along as the return value to the scheduled job's onStartJob() callback. + * @return Whether ongoing work will continue. The return value here will be passed along as the + * return value to the scheduled job's onStartJob() callback. */ public boolean beginFullBackup(FullBackupJob scheduledJob) { final long now = System.currentTimeMillis(); @@ -2012,33 +2032,34 @@ public class UserBackupManagerService { // the job driving automatic backups; that job will be scheduled again when // the user enables backup. if (DEBUG) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "beginFullBackup but enabled=" + mEnabled - + " setupComplete=" + mSetupComplete + "; ignoring")); + Slog.i( + TAG, + mLogIdMsg + + "beginFullBackup but enabled=" + + mEnabled + + " setupComplete=" + + mSetupComplete + + "; ignoring"); } return false; } // Don't run the backup if we're in battery saver mode, but reschedule // to try again in the not-so-distant future. - final PowerSaveState result = - mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP); + final PowerSaveState result = mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP); if (result.batterySaverEnabled) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, - "Deferring scheduled full backups in battery saver mode")); - FullBackupJob.schedule(mUserId, mContext, keyValueBackupInterval, - /* userBackupManagerService */ this); + Slog.i(TAG, mLogIdMsg + "Deferring scheduled full backups in battery saver mode"); + FullBackupJob.schedule( + mUserId, mContext, keyValueBackupInterval, /* userBackupManagerService */ this); return false; } - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning scheduled full backup operation")); + Slog.i(TAG, mLogIdMsg + "Beginning scheduled full backup operation"); // Great; we're able to run full backup jobs now. See if we have any work to do. synchronized (mQueueLock) { if (mRunningFullBackupTask != null) { - Slog.e( - TAG, - addUserIdToLogMessage( - mUserId, "Backup triggered but one already/still running!")); + Slog.e(TAG, mLogIdMsg + "Backup triggered but one already/still running!"); return false; } @@ -2053,8 +2074,7 @@ public class UserBackupManagerService { // have emptied the queue. if (mFullBackupQueue.size() == 0) { // no work to do so just bow out - Slog.i(TAG, - addUserIdToLogMessage(mUserId, "Backup queue empty; doing nothing")); + Slog.i(TAG, mLogIdMsg + "Backup queue empty; doing nothing"); runBackup = false; break; } @@ -2064,10 +2084,7 @@ public class UserBackupManagerService { String transportName = mTransportManager.getCurrentTransportName(); if (!fullBackupAllowable(transportName)) { if (DEBUG) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, "Preconditions not met; not running full backup")); + Slog.i(TAG, mLogIdMsg + "Preconditions not met; not running full backup"); } runBackup = false; // Typically this means we haven't run a key/value backup yet. Back off @@ -2085,18 +2102,16 @@ public class UserBackupManagerService { if (DEBUG) { Slog.i( TAG, - addUserIdToLogMessage( - mUserId, - "Device ready but too early to back up next app")); + mLogIdMsg + "Device ready but too early to back up next app"); } // Wait until the next app in the queue falls due for a full data backup latency = fullBackupInterval - timeSinceRun; - break; // we know we aren't doing work yet, so bail. + break; // we know we aren't doing work yet, so bail. } try { - PackageInfo appInfo = mPackageManager.getPackageInfoAsUser( - entry.packageName, 0, mUserId); + PackageInfo appInfo = + mPackageManager.getPackageInfoAsUser(entry.packageName, 0, mUserId); if (!mScheduledBackupEligibility.appGetsFullBackup(appInfo)) { // The head app isn't supposed to get full-data backups [any more]; // so we cull it and force a loop around to consider the new head @@ -2104,12 +2119,11 @@ public class UserBackupManagerService { if (DEBUG) { Slog.i( TAG, - addUserIdToLogMessage( - mUserId, - "Culling package " - + entry.packageName - + " in full-backup queue but not" - + " eligible")); + mLogIdMsg + + "Culling package " + + entry.packageName + + " in full-backup queue but not" + + " eligible"); } mFullBackupQueue.remove(0); headBusy = true; // force the while() condition @@ -2117,19 +2131,24 @@ public class UserBackupManagerService { } final int privFlags = appInfo.applicationInfo.privateFlags; - headBusy = (privFlags & PRIVATE_FLAG_BACKUP_IN_FOREGROUND) == 0 - && mActivityManagerInternal.isAppForeground( - appInfo.applicationInfo.uid); + headBusy = + (privFlags & PRIVATE_FLAG_BACKUP_IN_FOREGROUND) == 0 + && mActivityManagerInternal.isAppForeground( + appInfo.applicationInfo.uid); if (headBusy) { - final long nextEligible = System.currentTimeMillis() - + BUSY_BACKOFF_MIN_MILLIS - + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ); + final long nextEligible = + System.currentTimeMillis() + + BUSY_BACKOFF_MIN_MILLIS + + mTokenGenerator.nextInt(BUSY_BACKOFF_FUZZ); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Slog.i(TAG, addUserIdToLogMessage(mUserId, - "Full backup time but " + entry.packageName - + " is busy; deferring to " + sdf.format( - new Date(nextEligible)))); + Slog.i( + TAG, + mLogIdMsg + + "Full backup time but " + + entry.packageName + + " is busy; deferring to " + + sdf.format(new Date(nextEligible))); // This relocates the app's entry from the head of the queue to // its order-appropriate position further down, so upon looping // a new candidate will be considered at the head. @@ -2147,21 +2166,22 @@ public class UserBackupManagerService { if (runBackup) { CountDownLatch latch = new CountDownLatch(1); - String[] pkg = new String[]{entry.packageName}; + String[] pkg = new String[] {entry.packageName}; try { - mRunningFullBackupTask = PerformFullTransportBackupTask.newWithCurrentTransport( - this, - mOperationStorage, - /* observer */ null, - pkg, - /* updateSchedule */ true, - scheduledJob, - latch, - /* backupObserver */ null, - /* monitor */ null, - /* userInitiated */ false, - "BMS.beginFullBackup()", - getEligibilityRulesForOperation(BackupDestination.CLOUD)); + mRunningFullBackupTask = + PerformFullTransportBackupTask.newWithCurrentTransport( + this, + mOperationStorage, + /* observer */ null, + pkg, + /* updateSchedule */ true, + scheduledJob, + latch, + /* backupObserver */ null, + /* monitor */ null, + /* userInitiated */ false, + "BMS.beginFullBackup()", + getEligibilityRulesForOperation(BackupDestination.CLOUD)); } catch (IllegalStateException e) { Slog.w(TAG, "Failed to start backup", e); runBackup = false; @@ -2169,12 +2189,15 @@ public class UserBackupManagerService { } if (!runBackup) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, - "Nothing pending full backup or failed to start the " - + "operation; rescheduling +" + latency)); - final long deferTime = latency; // pin for the closure - FullBackupJob.schedule(mUserId, mContext, deferTime, - /* userBackupManagerService */ this); + Slog.i( + TAG, + mLogIdMsg + + "Nothing pending full backup or failed to start the " + + "operation; rescheduling +" + + latency); + final long deferTime = latency; // pin for the closure + FullBackupJob.schedule( + mUserId, mContext, deferTime, /* userBackupManagerService */ this); return false; } @@ -2195,21 +2218,22 @@ public class UserBackupManagerService { public void endFullBackup() { // offload the mRunningFullBackupTask.handleCancel() call to another thread, // as we might have to wait for mCancelLock - Runnable endFullBackupRunnable = new Runnable() { - @Override - public void run() { - PerformFullTransportBackupTask pftbt = null; - synchronized (mQueueLock) { - if (mRunningFullBackupTask != null) { - pftbt = mRunningFullBackupTask; + Runnable endFullBackupRunnable = + new Runnable() { + @Override + public void run() { + PerformFullTransportBackupTask pftbt = null; + synchronized (mQueueLock) { + if (mRunningFullBackupTask != null) { + pftbt = mRunningFullBackupTask; + } + } + if (pftbt != null) { + Slog.i(TAG, mLogIdMsg + "Telling running backup to stop"); + pftbt.handleCancel(true); + } } - } - if (pftbt != null) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Telling running backup to stop")); - pftbt.handleCancel(true); - } - } - }; + }; new Thread(endFullBackupRunnable, "end-full-backup").start(); } @@ -2217,7 +2241,7 @@ public class UserBackupManagerService { public void restoreWidgetData(String packageName, byte[] widgetData) { // Apply the restored widget state and generate the ID update for the app if (DEBUG) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Incorporating restored widget data")); + Slog.i(TAG, mLogIdMsg + "Incorporating restored widget data"); } AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, mUserId); } @@ -2235,13 +2259,12 @@ public class UserBackupManagerService { if (targets == null) { Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "dataChanged but no participant pkg='" - + packageName - + "'" - + " uid=" - + Binder.getCallingUid())); + mLogIdMsg + + "dataChanged but no participant pkg='" + + packageName + + "'" + + " uid=" + + Binder.getCallingUid()); return; } @@ -2253,10 +2276,7 @@ public class UserBackupManagerService { BackupRequest req = new BackupRequest(packageName); if (mPendingBackups.put(packageName, req) == null) { if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "Now staging backup of " + packageName)); + Slog.d(TAG, mLogIdMsg + "Now staging backup of " + packageName); } // Journal this request in case of crash. The put() @@ -2268,16 +2288,18 @@ public class UserBackupManagerService { } // ...and schedule a backup pass if necessary - KeyValueBackupJob.schedule(mUserId, mContext, - /* userBackupManagerService */ this); + KeyValueBackupJob.schedule(mUserId, mContext, /* userBackupManagerService */ this); } // Note: packageName is currently unused, but may be in the future private HashSet<String> dataChangedTargets(String packageName) { // If the caller does not hold the BACKUP permission, it can only request a // backup of its own data. - if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(), - Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) { + if ((mContext.checkPermission( + android.Manifest.permission.BACKUP, + Binder.getCallingPid(), + Binder.getCallingUid())) + == PackageManager.PERMISSION_DENIED) { synchronized (mBackupParticipants) { return mBackupParticipants.get(Binder.getCallingUid()); } @@ -2298,10 +2320,7 @@ public class UserBackupManagerService { if (mJournal == null) mJournal = DataChangedJournal.newJournal(mJournalDir); mJournal.addPackage(str); } catch (IOException e) { - Slog.e( - TAG, - addUserIdToLogMessage(mUserId, "Can't write " + str + " to backup journal"), - e); + Slog.e(TAG, mLogIdMsg + "Can't write " + str + " to backup journal", e); mJournal = null; } } @@ -2314,31 +2333,28 @@ public class UserBackupManagerService { if (targets == null) { Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "dataChanged but no participant pkg='" - + packageName - + "'" - + " uid=" - + Binder.getCallingUid())); + mLogIdMsg + + "dataChanged but no participant pkg='" + + packageName + + "'" + + " uid=" + + Binder.getCallingUid()); return; } - mBackupHandler.post(new Runnable() { - public void run() { - dataChangedImpl(packageName, targets); - } - }); + mBackupHandler.post( + new Runnable() { + public void run() { + dataChangedImpl(packageName, targets); + } + }); } /** Run an initialize operation for the given transport. */ public void initializeTransports(String[] transportNames, IBackupObserver observer) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "initializeTransport"); - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "initializeTransport(): " + Arrays.asList(transportNames))); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "initializeTransport"); + Slog.d(TAG, mLogIdMsg + "initializeTransport(): " + Arrays.asList(transportNames)); final long oldId = Binder.clearCallingIdentity(); try { @@ -2351,32 +2367,23 @@ public class UserBackupManagerService { } } - /** - * Sets the work profile serial number of the ancestral work profile. - */ + /** Sets the work profile serial number of the ancestral work profile. */ public void setAncestralSerialNumber(long ancestralSerialNumber) { - mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, - "setAncestralSerialNumber"); - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "Setting ancestral work profile id to " + ancestralSerialNumber)); + mContext.enforceCallingPermission( + android.Manifest.permission.BACKUP, "setAncestralSerialNumber"); + Slog.d(TAG, mLogIdMsg + "Setting ancestral work profile id to " + ancestralSerialNumber); try (RandomAccessFile af = new RandomAccessFile(getAncestralSerialNumberFile(), /* mode */ "rwd")) { af.writeLong(ancestralSerialNumber); } catch (IOException e) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Unable to write to work profile serial mapping file:"), - e); + Slog.w(TAG, mLogIdMsg + "Unable to write to work profile serial mapping file:", e); } } /** - * Returns the work profile serial number of the ancestral device. This will be set by - * {@link #setAncestralSerialNumber(long)}. Will return {@code -1} if not set. + * Returns the work profile serial number of the ancestral device. This will be set by {@link + * #setAncestralSerialNumber(long)}. Will return {@code -1} if not set. */ public long getAncestralSerialNumber() { try (RandomAccessFile af = @@ -2385,20 +2392,15 @@ public class UserBackupManagerService { } catch (FileNotFoundException e) { // It's OK not to have the file present, so we just return -1 to indicate no value. } catch (IOException e) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Unable to read work profile serial number file:"), - e); + Slog.w(TAG, mLogIdMsg + "Unable to read work profile serial number file:", e); } return -1; } private File getAncestralSerialNumberFile() { if (mAncestralSerialNumberFile == null) { - mAncestralSerialNumberFile = new File( - UserBackupManagerFiles.getBaseStateDir(getUserId()), - SERIAL_ID_FILE); + mAncestralSerialNumberFile = + new File(UserBackupManagerFiles.getBaseStateDir(getUserId()), SERIAL_ID_FILE); } return mAncestralSerialNumberFile; } @@ -2408,39 +2410,36 @@ public class UserBackupManagerService { mAncestralSerialNumberFile = ancestralSerialNumberFile; } - /** Clear the given package's backup data from the current transport. */ public void clearBackupData(String transportName, String packageName) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "clearBackupData() of " + packageName + " on " + transportName)); + Slog.d(TAG, mLogIdMsg + "clearBackupData() of " + packageName + " on " + transportName); PackageInfo info; try { - info = mPackageManager.getPackageInfoAsUser(packageName, - PackageManager.GET_SIGNING_CERTIFICATES, mUserId); + info = + mPackageManager.getPackageInfoAsUser( + packageName, PackageManager.GET_SIGNING_CERTIFICATES, mUserId); } catch (NameNotFoundException e) { Slog.d( TAG, - addUserIdToLogMessage( - mUserId, - "No such package '" + packageName + "' - not clearing backup data")); + mLogIdMsg + "No such package '" + packageName + "' - not clearing backup data"); return; } // If the caller does not hold the BACKUP permission, it can only request a // wipe of its own backed-up data. Set<String> apps; - if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(), - Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) { + if ((mContext.checkPermission( + android.Manifest.permission.BACKUP, + Binder.getCallingPid(), + Binder.getCallingUid())) + == PackageManager.PERMISSION_DENIED) { apps = mBackupParticipants.get(Binder.getCallingUid()); } else { // a caller with full permission can ask to back up any participating app // !!! TODO: allow data-clear of ANY app? if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, "Privileged caller, allowing clear of other apps")); + Slog.v(TAG, mLogIdMsg + "Privileged caller, allowing clear of other apps"); } apps = mProcessedPackagesJournal.getPackagesCopy(); } @@ -2448,30 +2447,33 @@ public class UserBackupManagerService { if (apps.contains(packageName)) { // found it; fire off the clear request if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage(mUserId, "Found the app - running clear process")); + Slog.v(TAG, mLogIdMsg + "Found the app - running clear process"); } mBackupHandler.removeMessages(MSG_RETRY_CLEAR); synchronized (mQueueLock) { TransportConnection transportConnection = - mTransportManager - .getTransportClient(transportName, "BMS.clearBackupData()"); + mTransportManager.getTransportClient( + transportName, "BMS.clearBackupData()"); if (transportConnection == null) { // transport is currently unregistered -- make sure to retry - Message msg = mBackupHandler.obtainMessage(MSG_RETRY_CLEAR, - new ClearRetryParams(transportName, packageName)); + Message msg = + mBackupHandler.obtainMessage( + MSG_RETRY_CLEAR, + new ClearRetryParams(transportName, packageName)); mBackupHandler.sendMessageDelayed(msg, TRANSPORT_RETRY_INTERVAL); return; } final long oldId = Binder.clearCallingIdentity(); try { - OnTaskFinishedListener listener = caller -> mTransportManager - .disposeOfTransportClient(transportConnection, caller); + OnTaskFinishedListener listener = + caller -> + mTransportManager.disposeOfTransportClient( + transportConnection, caller); mWakelock.acquire(); - Message msg = mBackupHandler.obtainMessage( - MSG_RUN_CLEAR, - new ClearParams(transportConnection, info, listener)); + Message msg = + mBackupHandler.obtainMessage( + MSG_RUN_CLEAR, + new ClearParams(transportConnection, info, listener)); mBackupHandler.sendMessage(msg); } finally { Binder.restoreCallingIdentity(oldId); @@ -2492,31 +2494,24 @@ public class UserBackupManagerService { final PowerSaveState result = mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP); if (result.batterySaverEnabled) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "Not running backup while in battery save mode")); + Slog.d(TAG, mLogIdMsg + "Not running backup while in battery save mode"); // Try again in several hours. - KeyValueBackupJob.schedule(mUserId, mContext, - /* userBackupManagerService */ this); + KeyValueBackupJob.schedule(mUserId, mContext, /* userBackupManagerService */ this); } else { - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Scheduling immediate backup pass")); + Slog.d(TAG, mLogIdMsg + "Scheduling immediate backup pass"); synchronized (getQueueLock()) { if (getPendingInits().size() > 0) { // If there are pending init operations, we process those and then settle // into the usual periodic backup schedule. if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, "Init pending at scheduled backup")); + Slog.v(TAG, mLogIdMsg + "Init pending at scheduled backup"); } try { getAlarmManager().cancel(mRunInitIntent); mRunInitIntent.send(); } catch (PendingIntent.CanceledException ce) { - Slog.w( - TAG, - addUserIdToLogMessage(mUserId, "Run init intent cancelled")); + Slog.w(TAG, mLogIdMsg + "Run init intent cancelled"); } return; } @@ -2526,8 +2521,11 @@ public class UserBackupManagerService { if (!isEnabled() || !isSetupComplete()) { Slog.w( TAG, - addUserIdToLogMessage(mUserId, "Backup pass but enabled=" + isEnabled() - + " setupComplete=" + isSetupComplete())); + mLogIdMsg + + "Backup pass but enabled=" + + isEnabled() + + " setupComplete=" + + isSetupComplete()); return; } @@ -2548,9 +2546,17 @@ public class UserBackupManagerService { * return to the caller until the backup has been completed. It requires on-screen confirmation * by the user. */ - public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, - boolean includeObbs, boolean includeShared, boolean doWidgets, boolean doAllApps, - boolean includeSystem, boolean compress, boolean doKeyValue, String[] pkgList) { + public void adbBackup( + ParcelFileDescriptor fd, + boolean includeApks, + boolean includeObbs, + boolean includeShared, + boolean doWidgets, + boolean doAllApps, + boolean includeSystem, + boolean compress, + boolean doKeyValue, + String[] pkgList) { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbBackup"); final int callingUserHandle = UserHandle.getCallingUserId(); @@ -2574,47 +2580,66 @@ public class UserBackupManagerService { final long oldId = Binder.clearCallingIdentity(); try { if (!mSetupComplete) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Backup not supported before setup")); + Slog.i(TAG, mLogIdMsg + "Backup not supported before setup"); return; } - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "Requesting backup: apks=" + includeApks + " obb=" + includeObbs + " shared=" - + includeShared + " all=" + doAllApps + " system=" + includeSystem - + " includekeyvalue=" + doKeyValue + " pkgs=" + Arrays.toString( - pkgList))); - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning adb backup...")); - - BackupEligibilityRules eligibilityRules = getEligibilityRulesForOperation( - BackupDestination.ADB_BACKUP); - AdbBackupParams params = new AdbBackupParams(fd, includeApks, includeObbs, - includeShared, doWidgets, doAllApps, includeSystem, compress, doKeyValue, - pkgList, eligibilityRules); + Slog.d( + TAG, + mLogIdMsg + + "Requesting backup: apks=" + + includeApks + + " obb=" + + includeObbs + + " shared=" + + includeShared + + " all=" + + doAllApps + + " system=" + + includeSystem + + " includekeyvalue=" + + doKeyValue + + " pkgs=" + + Arrays.toString(pkgList)); + Slog.i(TAG, mLogIdMsg + "Beginning adb backup..."); + + BackupEligibilityRules eligibilityRules = + getEligibilityRulesForOperation(BackupDestination.ADB_BACKUP); + AdbBackupParams params = + new AdbBackupParams( + fd, + includeApks, + includeObbs, + includeShared, + doWidgets, + doAllApps, + includeSystem, + compress, + doKeyValue, + pkgList, + eligibilityRules); final int token = generateRandomIntegerToken(); synchronized (mAdbBackupRestoreConfirmations) { mAdbBackupRestoreConfirmations.put(token, params); } // start up the confirmation UI - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Starting backup confirmation UI")); + Slog.d(TAG, mLogIdMsg + "Starting backup confirmation UI"); if (!startConfirmationUi(token, FullBackup.FULL_BACKUP_INTENT_ACTION)) { - Slog.e( - TAG, - addUserIdToLogMessage(mUserId, "Unable to launch backup confirmation UI")); + Slog.e(TAG, mLogIdMsg + "Unable to launch backup confirmation UI"); mAdbBackupRestoreConfirmations.delete(token); return; } // make sure the screen is lit for the user interaction - mPowerManager.userActivity(SystemClock.uptimeMillis(), - PowerManager.USER_ACTIVITY_EVENT_OTHER, - 0); + mPowerManager.userActivity( + SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); // start the confirmation countdown startConfirmationTimeout(token, params); // wait for the backup to be performed - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Waiting for backup completion...")); + Slog.d(TAG, mLogIdMsg + "Waiting for backup completion..."); waitForCompletion(params); } finally { try { @@ -2622,19 +2647,17 @@ public class UserBackupManagerService { } catch (IOException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "IO error closing output for adb backup: " + e.getMessage())); + mLogIdMsg + "IO error closing output for adb backup: " + e.getMessage()); } Binder.restoreCallingIdentity(oldId); - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Adb backup processing complete.")); + Slog.d(TAG, mLogIdMsg + "Adb backup processing complete."); } } /** Run a full backup pass for the given packages. Used by 'adb shell bmgr'. */ public void fullTransportBackup(String[] pkgNames) { - mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, - "fullTransportBackup"); + mContext.enforceCallingPermission( + android.Manifest.permission.BACKUP, "fullTransportBackup"); final int callingUserHandle = UserHandle.getCallingUserId(); // TODO: http://b/22388012 if (callingUserHandle != UserHandle.USER_SYSTEM) { @@ -2643,30 +2666,27 @@ public class UserBackupManagerService { String transportName = mTransportManager.getCurrentTransportName(); if (!fullBackupAllowable(transportName)) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, - "Full backup not currently possible -- key/value backup not yet run?")); + Slog.i(TAG, mLogIdMsg + "Full backup not possible. Key/value backup not yet run?"); } else { - Slog.d(TAG, addUserIdToLogMessage(mUserId, "fullTransportBackup()")); + Slog.d(TAG, mLogIdMsg + "fullTransportBackup()"); final long oldId = Binder.clearCallingIdentity(); try { CountDownLatch latch = new CountDownLatch(1); - Runnable task = PerformFullTransportBackupTask.newWithCurrentTransport( - this, - mOperationStorage, - /* observer */ null, - pkgNames, - /* updateSchedule */ false, - /* runningJob */ null, - latch, - /* backupObserver */ null, - /* monitor */ null, - /* userInitiated */ false, - "BMS.fullTransportBackup()", - getEligibilityRulesForOperation(BackupDestination.CLOUD)); + Runnable task = + PerformFullTransportBackupTask.newWithCurrentTransport( + this, + mOperationStorage, + /* observer */ null, + pkgNames, + /* updateSchedule */ false, + /* runningJob */ null, + latch, + /* backupObserver */ null, + /* monitor */ null, + /* userInitiated */ false, + "BMS.fullTransportBackup()", + getEligibilityRulesForOperation(BackupDestination.CLOUD)); // Acquiring wakelock for PerformFullTransportBackupTask before its start. mWakelock.acquire(); (new Thread(task, "full-transport-master")).start(); @@ -2692,7 +2712,7 @@ public class UserBackupManagerService { } } - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Done with full transport backup.")); + Slog.d(TAG, mLogIdMsg + "Done with full transport backup."); } /** @@ -2711,13 +2731,11 @@ public class UserBackupManagerService { try { if (!mSetupComplete) { - Slog.i( - TAG, - addUserIdToLogMessage(mUserId, "Full restore not permitted before setup")); + Slog.i(TAG, mLogIdMsg + "Full restore not permitted before setup"); return; } - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Beginning restore...")); + Slog.i(TAG, mLogIdMsg + "Beginning restore..."); AdbRestoreParams params = new AdbRestoreParams(fd); final int token = generateRandomIntegerToken(); @@ -2726,38 +2744,31 @@ public class UserBackupManagerService { } // start up the confirmation UI - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "Starting restore confirmation UI, token=" + token)); + Slog.d(TAG, mLogIdMsg + "Starting restore confirmation UI, token=" + token); if (!startConfirmationUi(token, FullBackup.FULL_RESTORE_INTENT_ACTION)) { - Slog.e( - TAG, - addUserIdToLogMessage(mUserId, "Unable to launch restore confirmation")); + Slog.e(TAG, mLogIdMsg + "Unable to launch restore confirmation"); mAdbBackupRestoreConfirmations.delete(token); return; } // make sure the screen is lit for the user interaction - mPowerManager.userActivity(SystemClock.uptimeMillis(), - PowerManager.USER_ACTIVITY_EVENT_OTHER, - 0); + mPowerManager.userActivity( + SystemClock.uptimeMillis(), PowerManager.USER_ACTIVITY_EVENT_OTHER, 0); // start the confirmation countdown startConfirmationTimeout(token, params); // wait for the restore to be performed - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Waiting for restore completion...")); + Slog.d(TAG, mLogIdMsg + "Waiting for restore completion..."); waitForCompletion(params); } finally { try { fd.close(); } catch (IOException e) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Error trying to close fd after adb restore: " + e)); + Slog.w(TAG, mLogIdMsg + "Error trying to close fd after adb restore: " + e); } Binder.restoreCallingIdentity(oldId); - Slog.i(TAG, addUserIdToLogMessage(mUserId, "adb restore processing complete.")); + Slog.i(TAG, mLogIdMsg + "adb restore processing complete."); } } @@ -2766,13 +2777,14 @@ public class UserBackupManagerService { * to the backup agent during restore. */ public void excludeKeysFromRestore(String packageName, List<String> keys) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "excludeKeysFromRestore"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "excludeKeysFromRestore"); mBackupPreferences.addExcludedKeys(packageName, keys); } - public void reportDelayedRestoreResult(String packageName, - List<BackupRestoreEventLogger.DataTypeResult> results) { + /** See {@link BackupManager#reportDelayedRestoreResult(BackupRestoreEventLogger)}. */ + public void reportDelayedRestoreResult( + String packageName, List<BackupRestoreEventLogger.DataTypeResult> results) { String transport = mTransportManager.getCurrentTransportName(); if (transport == null) { Slog.w(TAG, "Failed to send delayed restore logs as no transport selected"); @@ -2781,26 +2793,34 @@ public class UserBackupManagerService { TransportConnection transportConnection = null; try { - PackageInfo packageInfo = getPackageManager().getPackageInfoAsUser(packageName, - PackageManager.PackageInfoFlags.of(/* value */ 0), getUserId()); + PackageInfo packageInfo = + getPackageManager() + .getPackageInfoAsUser( + packageName, + PackageManager.PackageInfoFlags.of(/* value */ 0), + getUserId()); - transportConnection = mTransportManager.getTransportClientOrThrow( - transport, /* caller */"BMS.reportDelayedRestoreResult"); - BackupTransportClient transportClient = transportConnection.connectOrThrow( - /* caller */ "BMS.reportDelayedRestoreResult"); + transportConnection = + mTransportManager.getTransportClientOrThrow( + transport, /* caller */ "BMS.reportDelayedRestoreResult"); + BackupTransportClient transportClient = + transportConnection.connectOrThrow( + /* caller */ "BMS.reportDelayedRestoreResult"); IBackupManagerMonitor monitor = transportClient.getBackupManagerMonitor(); - BackupManagerMonitorEventSender mBackupManagerMonitorEventSender = + BackupManagerMonitorEventSender mBackupManagerMonitorEventSender = getBMMEventSender(monitor); - mBackupManagerMonitorEventSender.sendAgentLoggingResults(packageInfo, results, - BackupAnnotations.OperationType.RESTORE); - } catch (NameNotFoundException | TransportNotAvailableException - | TransportNotRegisteredException | RemoteException e) { + mBackupManagerMonitorEventSender.sendAgentLoggingResults( + packageInfo, results, BackupAnnotations.OperationType.RESTORE); + } catch (NameNotFoundException + | TransportNotAvailableException + | TransportNotRegisteredException + | RemoteException e) { Slog.w(TAG, "Failed to send delayed restore logs: " + e); } finally { if (transportConnection != null) { - mTransportManager.disposeOfTransportClient(transportConnection, - /* caller */"BMS.reportDelayedRestoreResult"); + mTransportManager.disposeOfTransportClient( + transportConnection, /* caller */ "BMS.reportDelayedRestoreResult"); } } } @@ -2808,7 +2828,8 @@ public class UserBackupManagerService { private boolean startConfirmationUi(int token, String action) { try { Intent confIntent = new Intent(action); - confIntent.setClassName("com.android.backupconfirm", + confIntent.setClassName( + "com.android.backupconfirm", "com.android.backupconfirm.BackupRestoreConfirmation"); confIntent.putExtra(FullBackup.CONF_TOKEN_INTENT_EXTRA, token); confIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); @@ -2821,11 +2842,14 @@ public class UserBackupManagerService { private void startConfirmationTimeout(int token, AdbParams params) { if (DEBUG) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Posting conf timeout msg after " - + TIMEOUT_FULL_CONFIRMATION + " millis")); + Slog.d( + TAG, + mLogIdMsg + + "Posting conf timeout msg after " + + TIMEOUT_FULL_CONFIRMATION + + " millis"); } - Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT, - token, 0, params); + Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT, token, 0, params); mBackupHandler.sendMessageDelayed(msg, TIMEOUT_FULL_CONFIRMATION); } @@ -2834,7 +2858,9 @@ public class UserBackupManagerService { while (!params.latch.get()) { try { params.latch.wait(); - } catch (InterruptedException e) { /* never interrupted */ } + } catch (InterruptedException e) { + /* never interrupted */ + } } } } @@ -2851,15 +2877,20 @@ public class UserBackupManagerService { * Confirm that the previously-requested full backup/restore operation can proceed. This is used * to require a user-facing disclosure about the operation. */ - public void acknowledgeAdbBackupOrRestore(int token, boolean allow, - String curPassword, String encPpassword, IFullBackupRestoreObserver observer) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "acknowledgeAdbBackupOrRestore : token=" + token + " allow=" + allow)); + public void acknowledgeAdbBackupOrRestore( + int token, + boolean allow, + String curPassword, + String encPpassword, + IFullBackupRestoreObserver observer) { + Slog.d( + TAG, + mLogIdMsg + "acknowledgeAdbBackupOrRestore : token=" + token + " allow=" + allow); // TODO: possibly require not just this signature-only permission, but even // require that the specific designated confirmation-UI app uid is the caller? - mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, - "acknowledgeAdbBackupOrRestore"); + mContext.enforceCallingPermission( + android.Manifest.permission.BACKUP, "acknowledgeAdbBackupOrRestore"); final long oldId = Binder.clearCallingIdentity(); try { @@ -2872,9 +2903,10 @@ public class UserBackupManagerService { mAdbBackupRestoreConfirmations.delete(token); if (allow) { - final int verb = params instanceof AdbBackupParams - ? MSG_RUN_ADB_BACKUP - : MSG_RUN_ADB_RESTORE; + final int verb = + params instanceof AdbBackupParams + ? MSG_RUN_ADB_BACKUP + : MSG_RUN_ADB_RESTORE; params.observer = observer; params.curPassword = curPassword; @@ -2882,28 +2914,20 @@ public class UserBackupManagerService { params.encryptPassword = encPpassword; if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "Sending conf message with verb " + verb)); + Slog.d(TAG, mLogIdMsg + "Sending conf message with verb " + verb); } mWakelock.acquire(); Message msg = mBackupHandler.obtainMessage(verb, params); mBackupHandler.sendMessage(msg); } else { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "User rejected full backup/restore operation")); + Slog.w(TAG, mLogIdMsg + "User rejected full backup/restore operation"); // indicate completion without having actually transferred any data signalAdbBackupRestoreCompletion(params); } } else { Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "Attempted to ack full backup/restore with invalid token")); + mLogIdMsg + "Attempted to ack full backup/restore with invalid token"); } } } finally { @@ -2922,10 +2946,10 @@ public class UserBackupManagerService { } private void setBackupEnabled(boolean enable, boolean persistToDisk) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "setBackupEnabled"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "setBackupEnabled"); - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Backup enabled => " + enable)); + Slog.i(TAG, mLogIdMsg + "Backup enabled => " + enable); final long oldId = Binder.clearCallingIdentity(); try { @@ -2944,23 +2968,25 @@ public class UserBackupManagerService { } synchronized void setFrameworkSchedulingEnabled(boolean isEnabled) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "setFrameworkSchedulingEnabled"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "setFrameworkSchedulingEnabled"); boolean wasEnabled = isFrameworkSchedulingEnabled(); if (wasEnabled == isEnabled) { return; } - Slog.i(TAG, addUserIdToLogMessage(mUserId, - (isEnabled ? "Enabling" : "Disabling") + " backup scheduling")); + Slog.i(TAG, mLogIdMsg + (isEnabled ? "Enabling" : "Disabling") + " backup scheduling"); final long oldId = Binder.clearCallingIdentity(); try { // TODO(b/264889098): Consider at a later point if we should us a sentinel file as // setBackupEnabled. - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.BACKUP_SCHEDULING_ENABLED, isEnabled ? 1 : 0, mUserId); + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.BACKUP_SCHEDULING_ENABLED, + isEnabled ? 1 : 0, + mUserId); if (!isEnabled) { KeyValueBackupJob.cancel(mUserId, mContext); @@ -2977,8 +3003,12 @@ public class UserBackupManagerService { synchronized boolean isFrameworkSchedulingEnabled() { // By default scheduling is enabled final int defaultSetting = 1; - int isEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.BACKUP_SCHEDULING_ENABLED, defaultSetting, mUserId); + int isEnabled = + Settings.Secure.getIntForUser( + mContext.getContentResolver(), + Settings.Secure.BACKUP_SCHEDULING_ENABLED, + defaultSetting, + mUserId); return isEnabled == 1; } @@ -2992,7 +3022,7 @@ public class UserBackupManagerService { } else if (!enable) { // No longer enabled, so stop running backups if (DEBUG) { - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Opting out of backup")); + Slog.i(TAG, mLogIdMsg + "Opting out of backup"); } KeyValueBackupJob.cancel(mUserId, mContext); @@ -3012,11 +3042,7 @@ public class UserBackupManagerService { dirName = mTransportManager.getTransportDirName(name); } catch (TransportNotRegisteredException e) { // Should never happen - Slog.e( - TAG, - addUserIdToLogMessage( - mUserId, "Unexpected unregistered transport"), - e); + Slog.e(TAG, mLogIdMsg + "Unexpected unregistered transport", e); return; } transportNames.add(name); @@ -3025,13 +3051,10 @@ public class UserBackupManagerService { // build the set of transports for which we are posting an init for (int i = 0; i < transportNames.size(); i++) { - recordInitPending( - true, - transportNames.get(i), - transportDirNames.get(i)); + recordInitPending(true, transportNames.get(i), transportDirNames.get(i)); } - mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), - mRunInitIntent); + mAlarmManager.set( + AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), mRunInitIntent); } } } @@ -3049,16 +3072,19 @@ public class UserBackupManagerService { /** Enable/disable automatic restore of app data at install time. */ public void setAutoRestore(boolean doAutoRestore) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "setAutoRestore"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "setAutoRestore"); - Slog.i(TAG, addUserIdToLogMessage(mUserId, "Auto restore => " + doAutoRestore)); + Slog.i(TAG, mLogIdMsg + "Auto restore => " + doAutoRestore); final long oldId = Binder.clearCallingIdentity(); try { synchronized (this) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.BACKUP_AUTO_RESTORE, doAutoRestore ? 1 : 0, mUserId); + Settings.Secure.putIntForUser( + mContext.getContentResolver(), + Settings.Secure.BACKUP_AUTO_RESTORE, + doAutoRestore ? 1 : 0, + mUserId); mAutoRestore = doAutoRestore; } } finally { @@ -3068,21 +3094,18 @@ public class UserBackupManagerService { /** Report whether the backup mechanism is currently enabled. */ public boolean isBackupEnabled() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "isBackupEnabled"); - return mEnabled; // no need to synchronize just to read it + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "isBackupEnabled"); + return mEnabled; // no need to synchronize just to read it } /** Report the name of the currently active transport. */ public String getCurrentTransport() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "getCurrentTransport"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "getCurrentTransport"); String currentTransport = mTransportManager.getCurrentTransportName(); if (DEBUG) { - Slog.v( - TAG, - addUserIdToLogMessage( - mUserId, "... getCurrentTransport() returning " + currentTransport)); + Slog.v(TAG, mLogIdMsg + "... getCurrentTransport() returning " + currentTransport); } return currentTransport; } @@ -3107,16 +3130,16 @@ public class UserBackupManagerService { /** Report all known, available backup transports by name. */ public String[] listAllTransports() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "listAllTransports"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "listAllTransports"); return mTransportManager.getRegisteredTransportNames(); } /** Report all known, available backup transports by component. */ public ComponentName[] listAllTransportComponents() { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "listAllTransportComponents"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "listAllTransportComponents"); return mTransportManager.getRegisteredTransportComponents(); } @@ -3129,18 +3152,17 @@ public class UserBackupManagerService { * @param transportComponent The identity of the transport being described. * @param name A {@link String} with the new name for the transport. This is NOT for * identification. MUST NOT be {@code null}. - * @param configurationIntent An {@link Intent} that can be passed to - * {@link Context#startActivity} in order to launch the transport's configuration UI. It may - * be {@code null} if the transport does not offer any user-facing configuration UI. + * @param configurationIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's configuration UI. It may be + * {@code null} if the transport does not offer any user-facing configuration UI. * @param currentDestinationString A {@link String} describing the destination to which the * transport is currently sending data. MUST NOT be {@code null}. - * @param dataManagementIntent An {@link Intent} that can be passed to - * {@link Context#startActivity} in order to launch the transport's data-management UI. It - * may be {@code null} if the transport does not offer any user-facing data - * management UI. + * @param dataManagementIntent An {@link Intent} that can be passed to {@link + * Context#startActivity} in order to launch the transport's data-management UI. It may be + * {@code null} if the transport does not offer any user-facing data management UI. * @param dataManagementLabel A {@link CharSequence} to be used as the label for the transport's - * data management affordance. This MUST be {@code null} when dataManagementIntent is - * {@code null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. + * data management affordance. This MUST be {@code null} when dataManagementIntent is {@code + * null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}. * @throws SecurityException If the UID of the calling process differs from the package UID of * {@code transportComponent} or if the caller does NOT have BACKUP permission. */ @@ -3175,8 +3197,7 @@ public class UserBackupManagerService { Objects.requireNonNull(transportComponent, "transportComponent can't be null"); Objects.requireNonNull(name, "name can't be null"); - Objects.requireNonNull( - currentDestinationString, "currentDestinationString can't be null"); + Objects.requireNonNull(currentDestinationString, "currentDestinationString can't be null"); Preconditions.checkArgument( (dataManagementIntent == null) == (dataManagementLabel == null), "dataManagementLabel should be null iff dataManagementIntent is null"); @@ -3211,7 +3232,7 @@ public class UserBackupManagerService { * selected transport. Returns {@code null} if the transport is not registered. * * @deprecated Use {@link #selectBackupTransportAsync(ComponentName, - * ISelectBackupTransportCallback)} instead. + * ISelectBackupTransportCallback)} instead. */ @Deprecated @Nullable @@ -3224,11 +3245,10 @@ public class UserBackupManagerService { if (!mTransportManager.isTransportRegistered(transportName)) { Slog.d( TAG, - addUserIdToLogMessage( - mUserId, - "Could not select transport " - + transportName - + ", as the transport is not registered.")); + mLogIdMsg + + "Could not select transport " + + transportName + + ", as the transport is not registered."); return null; } @@ -3236,12 +3256,11 @@ public class UserBackupManagerService { updateStateForTransport(transportName); Slog.d( TAG, - addUserIdToLogMessage( - mUserId, - "selectBackupTransport(transport = " - + transportName - + "): previous transport = " - + previousTransportName)); + mLogIdMsg + + "selectBackupTransport(transport = " + + transportName + + "): previous transport = " + + previousTransportName); return previousTransportName; } finally { Binder.restoreCallingIdentity(oldId); @@ -3262,9 +3281,7 @@ public class UserBackupManagerService { String transportString = transportComponent.flattenToShortString(); Slog.d( TAG, - addUserIdToLogMessage( - mUserId, - "selectBackupTransportAsync(transport = " + transportString + ")")); + mLogIdMsg + "selectBackupTransportAsync(transport = " + transportString + ")"); mBackupHandler.post( () -> { String transportName = null; @@ -3276,10 +3293,7 @@ public class UserBackupManagerService { mTransportManager.getTransportName(transportComponent); updateStateForTransport(transportName); } catch (TransportNotRegisteredException e) { - Slog.e( - TAG, - addUserIdToLogMessage( - mUserId, "Transport got unregistered")); + Slog.e(TAG, mLogIdMsg + "Transport got unregistered"); result = BackupManager.ERROR_TRANSPORT_UNAVAILABLE; } } @@ -3293,10 +3307,9 @@ public class UserBackupManagerService { } catch (RemoteException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "ISelectBackupTransportCallback listener not" - + " available")); + mLogIdMsg + + "ISelectBackupTransportCallback listener not" + + " available"); } }); } finally { @@ -3306,8 +3319,11 @@ public class UserBackupManagerService { private void updateStateForTransport(String newTransportName) { // Publish the name change - Settings.Secure.putStringForUser(mContext.getContentResolver(), - Settings.Secure.BACKUP_TRANSPORT, newTransportName, mUserId); + Settings.Secure.putStringForUser( + mContext.getContentResolver(), + Settings.Secure.BACKUP_TRANSPORT, + newTransportName, + mUserId); // And update our current-dataset bookkeeping String callerLogString = "BMS.updateStateForTransport()"; @@ -3315,8 +3331,8 @@ public class UserBackupManagerService { mTransportManager.getTransportClient(newTransportName, callerLogString); if (transportConnection != null) { try { - BackupTransportClient transport = transportConnection.connectOrThrow( - callerLogString); + BackupTransportClient transport = + transportConnection.connectOrThrow(callerLogString); mCurrentToken = transport.getCurrentRestoreSet(); } catch (Exception e) { // Oops. We can't know the current dataset token, so reset and figure it out @@ -3324,21 +3340,19 @@ public class UserBackupManagerService { mCurrentToken = 0; Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "Transport " - + newTransportName - + " not available: current token = 0")); + mLogIdMsg + + "Transport " + + newTransportName + + " not available: current token = 0"); } mTransportManager.disposeOfTransportClient(transportConnection, callerLogString); } else { Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "Transport " - + newTransportName - + " not registered: current token = 0")); + mLogIdMsg + + "Transport " + + newTransportName + + " not registered: current token = 0"); // The named transport isn't registered, so we can't know what its current dataset token // is. Reset as above. mCurrentToken = 0; @@ -3351,24 +3365,20 @@ public class UserBackupManagerService { * returns {@code null}. */ public Intent getConfigurationIntent(String transportName) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "getConfigurationIntent"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "getConfigurationIntent"); try { Intent intent = mTransportManager.getTransportConfigurationIntent(transportName); if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "getConfigurationIntent() returning intent " + intent)); + Slog.d(TAG, mLogIdMsg + "getConfigurationIntent() returning intent " + intent); } return intent; } catch (TransportNotRegisteredException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "Unable to get configuration intent from transport: " - + e.getMessage())); + mLogIdMsg + + "Unable to get configuration intent from transport: " + + e.getMessage()); return null; } } @@ -3389,42 +3399,36 @@ public class UserBackupManagerService { try { String string = mTransportManager.getTransportCurrentDestinationString(transportName); if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "getDestinationString() returning " + string)); + Slog.d(TAG, mLogIdMsg + "getDestinationString() returning " + string); } return string; } catch (TransportNotRegisteredException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "Unable to get destination string from transport: " + e.getMessage())); + mLogIdMsg + + "Unable to get destination string from transport: " + + e.getMessage()); return null; } } /** Supply the manage-data intent for the given transport. */ public Intent getDataManagementIntent(String transportName) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "getDataManagementIntent"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "getDataManagementIntent"); try { Intent intent = mTransportManager.getTransportDataManagementIntent(transportName); if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "getDataManagementIntent() returning intent " + intent)); + Slog.d(TAG, mLogIdMsg + "getDataManagementIntent() returning intent " + intent); } return intent; } catch (TransportNotRegisteredException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "Unable to get management intent from transport: " + e.getMessage())); + mLogIdMsg + + "Unable to get management intent from transport: " + + e.getMessage()); return null; } } @@ -3434,24 +3438,19 @@ public class UserBackupManagerService { * transport. */ public CharSequence getDataManagementLabel(String transportName) { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, - "getDataManagementLabel"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BACKUP, "getDataManagementLabel"); try { CharSequence label = mTransportManager.getTransportDataManagementLabel(transportName); if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage( - mUserId, "getDataManagementLabel() returning " + label)); + Slog.d(TAG, mLogIdMsg + "getDataManagementLabel() returning " + label); } return label; } catch (TransportNotRegisteredException e) { Slog.e( TAG, - addUserIdToLogMessage( - mUserId, - "Unable to get management label from transport: " + e.getMessage())); + mLogIdMsg + "Unable to get management label from transport: " + e.getMessage()); return null; } } @@ -3464,57 +3463,64 @@ public class UserBackupManagerService { if (Binder.getCallingUid() != Process.SYSTEM_UID) { Slog.w( TAG, - addUserIdToLogMessage( - mUserId, - "Non-system process uid=" - + Binder.getCallingUid() - + " attemping install-time restore")); + mLogIdMsg + + "Non-system process uid=" + + Binder.getCallingUid() + + " attemping install-time restore"); return; } boolean skip = false; long restoreSet = getAvailableRestoreToken(packageName); - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "restoreAtInstall pkg=" + packageName + " token=" + Integer.toHexString(token) - + " restoreSet=" + Long.toHexString(restoreSet))); + Slog.d( + TAG, + mLogIdMsg + + "restoreAtInstall pkg=" + + packageName + + " token=" + + Integer.toHexString(token) + + " restoreSet=" + + Long.toHexString(restoreSet)); if (restoreSet == 0) { - if (DEBUG) Slog.i(TAG, addUserIdToLogMessage(mUserId, "No restore set")); + if (DEBUG) Slog.i(TAG, mLogIdMsg + "No restore set"); skip = true; } - BackupManagerMonitorEventSender mBMMEventSender = - getBMMEventSender(/*monitor=*/ null); + BackupManagerMonitorEventSender mBMMEventSender = getBMMEventSender(/* monitor= */ null); PackageInfo packageInfo = getPackageInfoForBMMLogging(packageName); TransportConnection transportConnection = mTransportManager.getCurrentTransportClient("BMS.restoreAtInstall()"); if (transportConnection == null) { - Slog.w(TAG, addUserIdToLogMessage(mUserId, "No transport client")); + Slog.w(TAG, mLogIdMsg + "No transport client"); skip = true; } else if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) { try { - BackupTransportClient transportClient = transportConnection.connectOrThrow( - "BMS.restoreAtInstall"); + BackupTransportClient transportClient = + transportConnection.connectOrThrow("BMS.restoreAtInstall"); mBMMEventSender.setMonitor(transportClient.getBackupManagerMonitor()); } catch (TransportNotAvailableException | RemoteException e) { mBMMEventSender.monitorEvent( - BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL, packageInfo, - BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null); + BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL, + packageInfo, + BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, + null); } } if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) { mBMMEventSender.monitorEvent( - BackupManagerMonitor.LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED, packageInfo, + BackupManagerMonitor.LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED, + packageInfo, BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, - mBMMEventSender.putMonitoringExtra(/*extras=*/null, + mBMMEventSender.putMonitoringExtra( + /* extras= */ null, BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE, BackupAnnotations.OperationType.RESTORE)); } if (!mAutoRestore) { - Slog.w(TAG, - addUserIdToLogMessage(mUserId, "Non-restorable state: auto=" + mAutoRestore)); + Slog.w(TAG, mLogIdMsg + "Non-restorable state: auto=" + mAutoRestore); skip = true; } @@ -3526,15 +3532,14 @@ public class UserBackupManagerService { mWakelock.acquire(); - OnTaskFinishedListener listener = caller -> { - mTransportManager.disposeOfTransportClient(transportConnection, caller); - mWakelock.release(); - }; + OnTaskFinishedListener listener = + caller -> { + mTransportManager.disposeOfTransportClient(transportConnection, caller); + mWakelock.release(); + }; if (DEBUG) { - Slog.d( - TAG, - addUserIdToLogMessage(mUserId, "Restore at install of " + packageName)); + Slog.d(TAG, mLogIdMsg + "Restore at install of " + packageName); } Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = @@ -3550,10 +3555,7 @@ public class UserBackupManagerService { mBackupHandler.sendMessage(msg); } catch (Exception e) { // Calling into the transport broke; back off and proceed with the installation. - Slog.e( - TAG, - addUserIdToLogMessage( - mUserId, "Unable to contact transport: " + e.getMessage())); + Slog.e(TAG, mLogIdMsg + "Unable to contact transport: " + e.getMessage()); skip = true; } } @@ -3563,9 +3565,11 @@ public class UserBackupManagerService { if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) { mBMMEventSender.monitorEvent( - BackupManagerMonitor.LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL, packageInfo, + BackupManagerMonitor.LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL, + packageInfo, BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY, - mBMMEventSender.putMonitoringExtra(/*extras=*/null, + mBMMEventSender.putMonitoringExtra( + /* extras= */ null, BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE, BackupAnnotations.OperationType.RESTORE)); } @@ -3576,10 +3580,12 @@ public class UserBackupManagerService { } // Tell the PackageManager to proceed with the post-install handling for this package. - Slog.d(TAG, addUserIdToLogMessage(mUserId, "Finishing install immediately")); + Slog.d(TAG, mLogIdMsg + "Finishing install immediately"); try { mPackageManagerBinder.finishPackageInstall(token, false); - } catch (RemoteException e) { /* can't happen */ } + } catch (RemoteException e) { + /* can't happen */ + } } } @@ -3592,8 +3598,9 @@ public class UserBackupManagerService { /** Hand off a restore session. */ public IRestoreSession beginRestoreSession(String packageName, String transport) { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "beginRestoreSession: pkg=" + packageName + " transport=" + transport)); + Slog.d( + TAG, + mLogIdMsg + "beginRestoreSession: pkg=" + packageName + " transport=" + transport); boolean needPermission = true; if (transport == null) { @@ -3604,10 +3611,7 @@ public class UserBackupManagerService { try { app = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId); } catch (NameNotFoundException nnf) { - Slog.w( - TAG, - addUserIdToLogMessage( - mUserId, "Asked to restore nonexistent pkg " + packageName)); + Slog.w(TAG, mLogIdMsg + "Asked to restore nonexistent pkg " + packageName); throw new IllegalArgumentException("Package " + packageName + " not found"); } @@ -3624,46 +3628,45 @@ public class UserBackupManagerService { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.BACKUP, "beginRestoreSession"); } else { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "restoring self on current transport; no permission needed")); + Slog.d(TAG, mLogIdMsg + "restoring self on current transport; no permission needed"); } int backupDestination; TransportConnection transportConnection = null; try { - transportConnection = mTransportManager.getTransportClientOrThrow( - transport, /* caller */"BMS.beginRestoreSession"); + transportConnection = + mTransportManager.getTransportClientOrThrow( + transport, /* caller */ "BMS.beginRestoreSession"); backupDestination = getBackupDestinationFromTransport(transportConnection); - } catch (TransportNotAvailableException | TransportNotRegisteredException + } catch (TransportNotAvailableException + | TransportNotRegisteredException | RemoteException e) { Slog.w(TAG, "Failed to get operation type from transport: " + e); return null; } finally { if (transportConnection != null) { - mTransportManager.disposeOfTransportClient(transportConnection, - /* caller */"BMS.beginRestoreSession"); + mTransportManager.disposeOfTransportClient( + transportConnection, /* caller */ "BMS.beginRestoreSession"); } } synchronized (this) { if (mActiveRestoreSession != null) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, "Restore session requested but one already active")); + Slog.i(TAG, mLogIdMsg + "Restore session requested but one already active"); return null; } if (mBackupRunning) { - Slog.i( - TAG, - addUserIdToLogMessage( - mUserId, - "Restore session requested but currently running backups")); + Slog.i(TAG, mLogIdMsg + "Restore session requested but currently running backups"); return null; } - mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport, - getEligibilityRulesForOperation(backupDestination)); - mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, + mActiveRestoreSession = + new ActiveRestoreSession( + this, + packageName, + transport, + getEligibilityRulesForOperation(backupDestination)); + mBackupHandler.sendEmptyMessageDelayed( + MSG_RESTORE_SESSION_TIMEOUT, mAgentTimeoutParameters.getRestoreSessionTimeoutMillis()); } return mActiveRestoreSession; @@ -3673,10 +3676,9 @@ public class UserBackupManagerService { public void clearRestoreSession(ActiveRestoreSession currentSession) { synchronized (this) { if (currentSession != mActiveRestoreSession) { - Slog.e(TAG, addUserIdToLogMessage(mUserId, "ending non-current restore session")); + Slog.e(TAG, mLogIdMsg + "ending non-current restore session"); } else { - Slog.d(TAG, addUserIdToLogMessage(mUserId, - "Clearing restore session and halting timeout")); + Slog.d(TAG, mLogIdMsg + "Clearing restore session and halting timeout"); mActiveRestoreSession = null; mBackupHandler.removeMessages(MSG_RESTORE_SESSION_TIMEOUT); } @@ -3688,11 +3690,14 @@ public class UserBackupManagerService { * outstanding asynchronous backup/restore operation. */ public void opComplete(int token, long result) { - mOperationStorage.onOperationComplete(token, result, callback -> { - Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(callback, result); - Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult); - mBackupHandler.sendMessage(msg); - }); + mOperationStorage.onOperationComplete( + token, + result, + callback -> { + Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(callback, result); + Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult); + mBackupHandler.sendMessage(msg); + }); } /** Checks if the package is eligible for backup. */ @@ -3748,10 +3753,16 @@ public class UserBackupManagerService { return getEligibilityRules(mPackageManager, mUserId, mContext, backupDestination); } - private static BackupEligibilityRules getEligibilityRules(PackageManager packageManager, - int userId, Context context, @BackupDestination int backupDestination) { - return new BackupEligibilityRules(packageManager, - LocalServices.getService(PackageManagerInternal.class), userId, context, + private static BackupEligibilityRules getEligibilityRules( + PackageManager packageManager, + int userId, + Context context, + @BackupDestination int backupDestination) { + return new BackupEligibilityRules( + packageManager, + LocalServices.getService(PackageManagerInternal.class), + userId, + context, backupDestination); } @@ -3793,20 +3804,20 @@ public class UserBackupManagerService { } private void dumpBMMEvents(PrintWriter pw) { - BackupManagerMonitorDumpsysUtils bm = - new BackupManagerMonitorDumpsysUtils(); + BackupManagerMonitorDumpsysUtils bm = new BackupManagerMonitorDumpsysUtils(); if (bm.deleteExpiredBMMEvents()) { pw.println("BACKUP MANAGER MONITOR EVENTS HAVE EXPIRED"); return; } File events = bm.getBMMEventsFile(); - if (events.length() == 0){ + if (events.length() == 0) { // We have not recorded BMMEvents yet. pw.println("NO BACKUP MANAGER MONITOR EVENTS"); return; - } else if (bm.isFileLargerThanSizeLimit(events)){ - pw.println("BACKUP MANAGER MONITOR EVENTS FILE OVER SIZE LIMIT - " - + "future events will not be recorded"); + } else if (bm.isFileLargerThanSizeLimit(events)) { + pw.println( + "BACKUP MANAGER MONITOR EVENTS FILE OVER SIZE LIMIT - " + + "future events will not be recorded"); } pw.println("START OF BACKUP MANAGER MONITOR EVENTS"); try (BufferedReader reader = new BufferedReader(new FileReader(events))) { @@ -3826,16 +3837,27 @@ public class UserBackupManagerService { // Add prefix for only non-system users so that system user dumpsys is the same as before String userPrefix = mUserId == UserHandle.USER_SYSTEM ? "" : "User " + mUserId + ":"; synchronized (mQueueLock) { - pw.println(userPrefix + "Backup Manager is " + (mEnabled ? "enabled" : "disabled") - + " / " + (!mSetupComplete ? "not " : "") + "setup complete / " - + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init"); + pw.println( + userPrefix + + "Backup Manager is " + + (mEnabled ? "enabled" : "disabled") + + " / " + + (!mSetupComplete ? "not " : "") + + "setup complete / " + + (this.mPendingInits.size() == 0 ? "not " : "") + + "pending init"); pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled")); if (mBackupRunning) pw.println("Backup currently running"); pw.println(isBackupOperationInProgress() ? "Backup in progress" : "No backups running"); - pw.println("Framework scheduling is " - + (isFrameworkSchedulingEnabled() ? "enabled" : "disabled")); - pw.println("Last backup pass started: " + mLastBackupPass - + " (now = " + System.currentTimeMillis() + ')'); + pw.println( + "Framework scheduling is " + + (isFrameworkSchedulingEnabled() ? "enabled" : "disabled")); + pw.println( + "Last backup pass started: " + + mLastBackupPass + + " (now = " + + System.currentTimeMillis() + + ')'); pw.println(" next scheduled: " + KeyValueBackupJob.nextScheduled(mUserId)); pw.println(userPrefix + "Transport whitelist:"); @@ -3848,21 +3870,27 @@ public class UserBackupManagerService { final String[] transports = listAllTransports(); if (transports != null) { for (String t : transports) { - pw.println((t.equals(mTransportManager.getCurrentTransportName()) ? " * " - : " ") + t); + pw.println( + (t.equals(mTransportManager.getCurrentTransportName()) + ? " * " + : " ") + + t); try { - File dir = new File(mBaseStateDir, - mTransportManager.getTransportDirName(t)); - pw.println(" destination: " - + mTransportManager.getTransportCurrentDestinationString(t)); - pw.println(" intent: " - + mTransportManager.getTransportConfigurationIntent(t)); + File dir = + new File(mBaseStateDir, mTransportManager.getTransportDirName(t)); + pw.println( + " destination: " + + mTransportManager.getTransportCurrentDestinationString( + t)); + pw.println( + " intent: " + + mTransportManager.getTransportConfigurationIntent(t)); for (File f : dir.listFiles()) { pw.println( " " + f.getName() + " - " + f.length() + " state bytes"); } } catch (Exception e) { - Slog.e(TAG, addUserIdToLogMessage(mUserId, "Error in transport"), e); + Slog.e(TAG, mLogIdMsg + "Error in transport", e); pw.println(" Error: " + e); } } @@ -3892,8 +3920,10 @@ public class UserBackupManagerService { } } - pw.println(userPrefix + "Ancestral packages: " - + (mAncestralPackages == null ? "none" : mAncestralPackages.size())); + pw.println( + userPrefix + + "Ancestral packages: " + + (mAncestralPackages == null ? "none" : mAncestralPackages.size())); if (mAncestralPackages != null) { for (String pkg : mAncestralPackages) { pw.println(" " + pkg); @@ -3919,29 +3949,35 @@ public class UserBackupManagerService { pw.println(entry.packageName); } pw.println(userPrefix + "Agent timeouts:"); - pw.println(" KvBackupAgentTimeoutMillis: " - + mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis()); - pw.println(" FullBackupAgentTimeoutMillis: " - + mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis()); - pw.println(" SharedBackupAgentTimeoutMillis: " - + mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis()); - pw.println(" RestoreAgentTimeoutMillis (system): " - + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis( - Process.FIRST_APPLICATION_UID - 1)); - pw.println(" RestoreAgentTimeoutMillis: " - + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis( - Process.FIRST_APPLICATION_UID)); - pw.println(" RestoreAgentFinishedTimeoutMillis: " - + mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis()); - pw.println(" QuotaExceededTimeoutMillis: " - + mAgentTimeoutParameters.getQuotaExceededTimeoutMillis()); - + pw.println( + " KvBackupAgentTimeoutMillis: " + + mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis()); + pw.println( + " FullBackupAgentTimeoutMillis: " + + mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis()); + pw.println( + " SharedBackupAgentTimeoutMillis: " + + mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis()); + pw.println( + " RestoreAgentTimeoutMillis (system): " + + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis( + Process.FIRST_APPLICATION_UID - 1)); + pw.println( + " RestoreAgentTimeoutMillis: " + + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis( + Process.FIRST_APPLICATION_UID)); + pw.println( + " RestoreAgentFinishedTimeoutMillis: " + + mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis()); + pw.println( + " QuotaExceededTimeoutMillis: " + + mAgentTimeoutParameters.getQuotaExceededTimeoutMillis()); } } @VisibleForTesting - @BackupDestination int getBackupDestinationFromTransport( - TransportConnection transportConnection) + @BackupDestination + int getBackupDestinationFromTransport(TransportConnection transportConnection) throws TransportNotAvailableException, RemoteException { if (!shouldUseNewBackupEligibilityRules()) { // Return the default to stick to the legacy behaviour. @@ -3950,8 +3986,9 @@ public class UserBackupManagerService { final long oldCallingId = Binder.clearCallingIdentity(); try { - BackupTransportClient transport = transportConnection.connectOrThrow( - /* caller */ "BMS.getBackupDestinationFromTransport"); + BackupTransportClient transport = + transportConnection.connectOrThrow( + /* caller */ "BMS.getBackupDestinationFromTransport"); if ((transport.getTransportFlags() & BackupAgent.FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) { return BackupDestination.DEVICE_TRANSFER; } else { @@ -3964,15 +4001,10 @@ public class UserBackupManagerService { @VisibleForTesting boolean shouldUseNewBackupEligibilityRules() { - return FeatureFlagUtils.isEnabled(mContext, - FeatureFlagUtils.SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES); + return FeatureFlagUtils.isEnabled( + mContext, FeatureFlagUtils.SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES); } - private static String addUserIdToLogMessage(int userId, String message) { - return "[UserID:" + userId + "] " + message; - } - - public IBackupManager getBackupManagerBinder() { return mBackupManagerBinder; } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 5edd9d7041ba..c385fbad02a5 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -482,21 +482,15 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } mVirtualDeviceLog.logCreated(deviceId, mOwnerUid); - if (Flags.vdmPublicApis()) { - mPublicVirtualDeviceObject = new VirtualDevice( - this, getDeviceId(), getPersistentDeviceId(), mParams.getName(), - getDisplayName()); - } else { - mPublicVirtualDeviceObject = new VirtualDevice( - this, getDeviceId(), getPersistentDeviceId(), mParams.getName()); - } + mPublicVirtualDeviceObject = new VirtualDevice( + this, getDeviceId(), getPersistentDeviceId(), mParams.getName(), getDisplayName()); mActivityPolicyExemptions = new ArraySet<>( mParams.getDevicePolicy(POLICY_TYPE_ACTIVITY) == DEVICE_POLICY_DEFAULT ? mParams.getBlockedActivities() : mParams.getAllowedActivities()); - if (Flags.vdmCustomIme() && mParams.getInputMethodComponent() != null) { + if (mParams.getInputMethodComponent() != null) { final String imeId = mParams.getInputMethodComponent().flattenToShortString(); Slog.d(TAG, "Setting custom input method " + imeId + " as default for virtual device " + deviceId); @@ -813,7 +807,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } // Clear any previously set custom IME components. - if (Flags.vdmCustomIme() && mParams.getInputMethodComponent() != null) { + if (mParams.getInputMethodComponent() != null) { InputMethodManagerInternal.get().setVirtualDeviceInputMethodForAllUsers( mDeviceId, null); } @@ -1357,10 +1351,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } private boolean hasCustomAudioInputSupportInternal() { - if (!Flags.vdmPublicApis()) { - return false; - } - if (!android.media.audiopolicy.Flags.audioMixTestApi()) { return false; } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java index a60fa693350c..0b335d318d64 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -318,16 +318,14 @@ public class VirtualDeviceManagerService extends SystemService { mVirtualDevices.remove(deviceId); } - if (Flags.vdmPublicApis()) { - mVirtualDeviceListeners.broadcast(listener -> { - try { - listener.onVirtualDeviceClosed(deviceId); - } catch (RemoteException e) { - Slog.i(TAG, "Failed to invoke onVirtualDeviceClosed listener: " - + e.getMessage()); - } - }); - } + mVirtualDeviceListeners.broadcast(listener -> { + try { + listener.onVirtualDeviceClosed(deviceId); + } catch (RemoteException e) { + Slog.i(TAG, "Failed to invoke onVirtualDeviceClosed listener: " + + e.getMessage()); + } + }); Intent i = new Intent(VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED); i.putExtra(VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID, deviceId); @@ -498,16 +496,14 @@ public class VirtualDeviceManagerService extends SystemService { mVirtualDevices.put(deviceId, virtualDevice); } - if (Flags.vdmPublicApis()) { - mVirtualDeviceListeners.broadcast(listener -> { - try { - listener.onVirtualDeviceCreated(deviceId); - } catch (RemoteException e) { - Slog.i(TAG, "Failed to invoke onVirtualDeviceCreated listener: " - + e.getMessage()); - } - }); - } + mVirtualDeviceListeners.broadcast(listener -> { + try { + listener.onVirtualDeviceCreated(deviceId); + } catch (RemoteException e) { + Slog.i(TAG, "Failed to invoke onVirtualDeviceCreated listener: " + + e.getMessage()); + } + }); Counter.logIncrementWithUid( "virtual_devices.value_virtual_devices_created_with_uid_count", attributionSource.getUid()); diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 6459016eec75..87222a60d82d 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -564,7 +564,8 @@ public class GestureLauncherService extends SystemService { return Settings.Secure.getIntForUser( context.getContentResolver(), Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, - LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER, + context.getResources().getInteger( + R.integer.config_doubleTapPowerGestureMultiTargetDefaultAction), userId); } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 600aa1fdaa04..644077a7e6bb 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -528,6 +528,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub public void systemServicesReady() { mStats.saveBatteryUsageStatsOnReset(mBatteryUsageStatsProvider, mPowerStatsStore, isBatteryUsageStatsAccumulationSupported()); + mStats.resetBatteryHistoryOnNewSession( + !Flags.extendedBatteryHistoryContinuousCollectionEnabled()); MultiStatePowerAttributor attributor = (MultiStatePowerAttributor) mPowerAttributor; mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_CPU, diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 2216f2769826..f7eaa159be30 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2553,13 +2553,12 @@ public final class ProcessList { final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); // We can't isolate app data and storage data as parent zygote already did that. - startResult = appZygote.getProcess().start(entryPoint, - app.processName, uid, uid, gids, runtimeFlags, mountExternal, + startResult = appZygote.startProcess(entryPoint, + app.processName, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, - app.info.dataDir, null, app.info.packageName, - /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp, - app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap, - false, false, false, + app.info.dataDir, app.info.packageName, isTopApp, + app.getDisabledCompatChanges(), pkgDataInfoMap, + allowlistedAppDataInfoMap, new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); } else { regularZygote = true; diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index c99e8c8ff799..d3a52543f321 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -155,6 +155,7 @@ public class SettingsToPropertiesMapper { "android_core_networking", "android_health_services", "android_sdk", + "android_kernel", "aoc", "app_widgets", "arc_next", diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index d76c04ac7f31..27e9e44f1090 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -4062,8 +4062,7 @@ class UserController implements Handler.Callback { synchronized (mUserSwitchingDialogLock) { dismissUserSwitchingDialog(null); mUserSwitchingDialog = new UserSwitchingDialog(mService.mContext, fromUser, toUser, - switchingFromSystemUserMessage, switchingToSystemUserMessage, - getWindowManager()); + switchingFromSystemUserMessage, switchingToSystemUserMessage); mUserSwitchingDialog.show(onShown); } } diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java index 2d7456471be4..d1fcb9d1ca37 100644 --- a/services/core/java/com/android/server/am/UserSwitchingDialog.java +++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java @@ -39,7 +39,6 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; -import android.provider.Settings; import android.util.Slog; import android.util.TypedValue; import android.view.View; @@ -53,7 +52,6 @@ import android.widget.TextView; import com.android.internal.R; import com.android.internal.util.ObjectUtils; import com.android.internal.util.UserIcons; -import com.android.server.wm.WindowManagerService; import java.util.concurrent.atomic.AtomicBoolean; @@ -80,14 +78,11 @@ class UserSwitchingDialog extends Dialog { protected final UserInfo mNewUser; private final String mSwitchingFromSystemUserMessage; private final String mSwitchingToSystemUserMessage; - private final WindowManagerService mWindowManager; protected final Context mContext; private final int mTraceCookie; - private final boolean mNeedToFreezeScreen; UserSwitchingDialog(Context context, UserInfo oldUser, UserInfo newUser, - String switchingFromSystemUserMessage, String switchingToSystemUserMessage, - WindowManagerService windowManager) { + String switchingFromSystemUserMessage, String switchingToSystemUserMessage) { super(context, R.style.Theme_Material_NoActionBar_Fullscreen); mContext = context; @@ -97,8 +92,6 @@ class UserSwitchingDialog extends Dialog { mSwitchingToSystemUserMessage = switchingToSystemUserMessage; mDisableAnimations = SystemProperties.getBoolean( "debug.usercontroller.disable_user_switching_dialog_animations", false); - mWindowManager = windowManager; - mNeedToFreezeScreen = !mDisableAnimations && !isUserSetupComplete(newUser); mTraceCookie = UserHandle.MAX_SECONDARY_USER_ID * oldUser.id + newUser.id; inflateContent(); @@ -183,11 +176,6 @@ class UserSwitchingDialog extends Dialog { : res.getString(R.string.user_switching_message, mNewUser.name); } - private boolean isUserSetupComplete(UserInfo user) { - return Settings.Secure.getIntForUser(mContext.getContentResolver(), - Settings.Secure.USER_SETUP_COMPLETE, /* default= */ 0, user.id) == 1; - } - @Override public void show() { asyncTraceBegin("dialog", 0); @@ -197,7 +185,6 @@ class UserSwitchingDialog extends Dialog { @Override public void dismiss() { super.dismiss(); - stopFreezingScreen(); asyncTraceEnd("dialog", 0); } @@ -205,7 +192,6 @@ class UserSwitchingDialog extends Dialog { if (DEBUG) Slog.d(TAG, "show called"); show(); startShowAnimation(() -> { - startFreezingScreen(); onShown.run(); }); } @@ -223,24 +209,6 @@ class UserSwitchingDialog extends Dialog { } } - private void startFreezingScreen() { - if (!mNeedToFreezeScreen) { - return; - } - traceBegin("startFreezingScreen"); - mWindowManager.startFreezingScreen(0, 0); - traceEnd("startFreezingScreen"); - } - - private void stopFreezingScreen() { - if (!mNeedToFreezeScreen) { - return; - } - traceBegin("stopFreezingScreen"); - mWindowManager.stopFreezingScreen(); - traceEnd("stopFreezingScreen"); - } - private void startShowAnimation(Runnable onAnimationEnd) { if (mDisableAnimations) { onAnimationEnd.run(); @@ -260,7 +228,7 @@ class UserSwitchingDialog extends Dialog { } private void startDismissAnimation(Runnable onAnimationEnd) { - if (mDisableAnimations || mNeedToFreezeScreen) { + if (mDisableAnimations) { // animations are disabled or screen is frozen, no need to play an animation onAnimationEnd.run(); return; @@ -352,14 +320,4 @@ class UserSwitchingDialog extends Dialog { Trace.asyncTraceEnd(TRACE_TAG, TAG + subTag, mTraceCookie + subCookie); if (DEBUG) Slog.d(TAG, "asyncTraceEnd-" + subTag); } - - private void traceBegin(String msg) { - if (DEBUG) Slog.d(TAG, "traceBegin-" + msg); - Trace.traceBegin(TRACE_TAG, msg); - } - - private void traceEnd(String msg) { - Trace.traceEnd(TRACE_TAG); - if (DEBUG) Slog.d(TAG, "traceEnd-" + msg); - } } diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 8a63f9a24ea3..d2073aaa834c 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2589,7 +2589,6 @@ public class AppOpsService extends IAppOpsService.Stub { Map<String, Ops> packages = uidState.pkgOps; Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator(); - boolean uidChanged = false; while (it.hasNext()) { Map.Entry<String, Ops> ent = it.next(); String packageName = ent.getKey(); @@ -2622,7 +2621,6 @@ public class AppOpsService extends IAppOpsService.Stub { newMode, UserHandle.getUserId(curOp.uid)); changed = true; - uidChanged = true; final int uid = curOp.uidState.uid; callbacks = addCallbacks(callbacks, curOp.op, uid, packageName, previousMode, mOpModeWatchers.get(curOp.op)); diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index b9b06701a11b..c125d2d2e8cd 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -256,6 +256,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.os.SomeArgs; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; +import com.android.modules.expresslog.Counter; import com.android.server.EventLogTags; import com.android.server.LocalManagerRegistry; import com.android.server.LocalServices; @@ -838,9 +839,49 @@ public class AudioService extends IAudioService.Stub new AudioServiceUserRestrictionsListener(); private final IAudioManagerNative mNativeShim = new IAudioManagerNative.Stub() { + static final String METRIC_COUNTERS_PLAYBACK_PARTIAL = + "media_audio.value_audio_playback_hardening_partial_restriction"; + static final String METRIC_COUNTERS_PLAYBACK_STRICT = + "media_audio.value_audio_playback_hardening_strict_would_restrict"; + + String getPackNameForUid(int uid) { + final long token = Binder.clearCallingIdentity(); + try { + final String[] names = AudioService.this.mContext. + getPackageManager().getPackagesForUid(uid); + if (names == null + || names.length == 0 + || TextUtils.isEmpty(names[0])) { + return "[" + uid + "]"; + } + return names[0]; + } finally { + Binder.restoreCallingIdentity(token); + } + } + // oneway @Override public void playbackHardeningEvent(int uid, byte type, boolean bypassed) { + if (Binder.getCallingUid() != Process.AUDIOSERVER_UID) { + return; + } + if (type == HardeningType.PARTIAL) { + Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_PARTIAL, uid); + } else if (type == HardeningType.FULL) { + Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_STRICT, uid); + } else { + Slog.wtf(TAG, "Unexpected hardening type" + type); + return; + } + String msg = "AudioHardening background playback " + + (bypassed ? "would be " : "") + + "muted for " + + getPackNameForUid(uid) + " (" + uid + "), " + + "level: " + (type == HardeningType.PARTIAL ? "partial" : "full"); + + AudioService.this.mHardeningLogger.enqueueAndSlog(msg, + bypassed ? EventLogger.Event.ALOGI : EventLogger.Event.ALOGW, TAG); } @Override @@ -1544,7 +1585,8 @@ public class AudioService extends IAudioService.Stub mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler); mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), mAppOps, - context.getPackageManager()); + context.getPackageManager(), + mHardeningLogger); } private void initVolumeStreamStates() { @@ -12691,6 +12733,7 @@ public class AudioService extends IAudioService.Stub static final int LOG_NB_EVENTS_DYN_POLICY = 10; static final int LOG_NB_EVENTS_SPATIAL = 30; static final int LOG_NB_EVENTS_SOUND_DOSE = 50; + static final int LOG_NB_EVENTS_HARDENING = 50; static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30; @@ -12729,6 +12772,9 @@ public class AudioService extends IAudioService.Stub mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY, "dynamic policy events (logged when command received by AudioService)"); + private final EventLogger mHardeningLogger = new EventLogger( + LOG_NB_EVENTS_HARDENING, "Hardening enforcement"); + private static final String[] RINGER_MODE_NAMES = new String[] { "SILENT", "VIBRATE", @@ -12803,7 +12849,7 @@ public class AudioService extends IAudioService.Stub pw.println("\nMessage handler is null"); } dumpFlags(pw); - mHardeningEnforcer.dump(pw); + mHardeningLogger.dump(pw); mMediaFocusControl.dump(pw); dumpStreamStates(pw); dumpVolumeGroups(pw); diff --git a/services/core/java/com/android/server/audio/HardeningEnforcer.java b/services/core/java/com/android/server/audio/HardeningEnforcer.java index 661111070aae..f69a810b314f 100644 --- a/services/core/java/com/android/server/audio/HardeningEnforcer.java +++ b/services/core/java/com/android/server/audio/HardeningEnforcer.java @@ -54,8 +54,7 @@ public class HardeningEnforcer { final ActivityManager mActivityManager; final PackageManager mPackageManager; - final EventLogger mEventLogger = new EventLogger(LOG_NB_EVENTS, - "Hardening enforcement"); + final EventLogger mEventLogger; // capacity = 4 for each of the focus request types static final SparseArray<String> METRIC_COUNTERS_FOCUS_DENIAL = new SparseArray<>(4); @@ -108,17 +107,13 @@ public class HardeningEnforcer { public static final int METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS = 300; public HardeningEnforcer(Context ctxt, boolean isAutomotive, AppOpsManager appOps, - PackageManager pm) { + PackageManager pm, EventLogger logger) { mContext = ctxt; mIsAutomotive = isAutomotive; mAppOps = appOps; mActivityManager = ctxt.getSystemService(ActivityManager.class); mPackageManager = pm; - } - - protected void dump(PrintWriter pw) { - // log - mEventLogger.dump(pw); + mEventLogger = logger; } /** diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 1c01fb9f19e0..e2e06b63c7d6 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -1745,7 +1745,6 @@ public final class PlaybackActivityMonitor eventValues[0] = eventValue; sEventLogger.enqueue( new PlayerEvent(piid, PLAYER_UPDATE_MUTED, eventValues)); - final AudioPlaybackConfiguration apc = mPlayers.get(piid); if (apc == null || !apc.handleMutedEvent(eventValue)) { break; // do not dispatch diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java index 78f71877afed..6122fdaafe77 100644 --- a/services/core/java/com/android/server/clipboard/ClipboardService.java +++ b/services/core/java/com/android/server/clipboard/ClipboardService.java @@ -17,8 +17,6 @@ package com.android.server.clipboard; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; -import static android.companion.virtual.VirtualDeviceManager.ACTION_VIRTUAL_DEVICE_REMOVED; -import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID; import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD; import static android.content.Context.DEVICE_ID_DEFAULT; @@ -46,7 +44,6 @@ import android.content.Context; import android.content.IClipboard; import android.content.IOnPrimaryClipChangedListener; import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.UserInfo; @@ -219,35 +216,7 @@ public class ClipboardService extends SystemService { @Override public void onStart() { publishBinderService(Context.CLIPBOARD_SERVICE, new ClipboardImpl()); - if (!android.companion.virtual.flags.Flags.vdmPublicApis() && mVdmInternal != null) { - registerVirtualDeviceBroadcastReceiver(); - } else if (android.companion.virtual.flags.Flags.vdmPublicApis() && mVdm != null) { - registerVirtualDeviceListener(); - } - } - - private void registerVirtualDeviceBroadcastReceiver() { - if (mVirtualDeviceRemovedReceiver != null) { - return; - } - mVirtualDeviceRemovedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (!intent.getAction().equals(ACTION_VIRTUAL_DEVICE_REMOVED)) { - return; - } - final int removedDeviceId = - intent.getIntExtra(EXTRA_VIRTUAL_DEVICE_ID, DEVICE_ID_INVALID); - synchronized (mLock) { - for (int i = mClipboards.numMaps() - 1; i >= 0; i--) { - mClipboards.delete(mClipboards.keyAt(i), removedDeviceId); - } - } - } - }; - IntentFilter filter = new IntentFilter(ACTION_VIRTUAL_DEVICE_REMOVED); - getContext().registerReceiver(mVirtualDeviceRemovedReceiver, filter, - Context.RECEIVER_NOT_EXPORTED); + registerVirtualDeviceListener(); } private void registerVirtualDeviceListener() { diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index 93d9b8d30a2e..25a2f60b85b2 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -643,8 +643,9 @@ final class ColorFade { .setSecure(isSecure) .setBLASTLayer(); mBLASTSurfaceControl = b.build(); - mBLASTBufferQueue = new BLASTBufferQueue("ColorFade", mBLASTSurfaceControl, - mDisplayWidth, mDisplayHeight, PixelFormat.TRANSLUCENT); + mBLASTBufferQueue = new BLASTBufferQueue("ColorFade", /*updateDestinationFrame*/ true); + mBLASTBufferQueue.update(mBLASTSurfaceControl, mDisplayWidth, mDisplayHeight, + PixelFormat.TRANSLUCENT); mSurface = mBLASTBufferQueue.createSurface(); } return true; diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index d37dd3018fde..b49c01b3e2a8 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -83,6 +83,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.boot.emulator.circular"; + private static final double DEFAULT_DISPLAY_SIZE = 24.0; + private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>(); private final Injector mInjector; @@ -526,6 +528,21 @@ final class LocalDisplayAdapter extends DisplayAdapter { private int getLogicalDensity() { DensityMapping densityMapping = getDisplayDeviceConfig().getDensityMapping(); if (densityMapping == null) { + if (getFeatureFlags().isBaseDensityForExternalDisplaysEnabled() + && !mStaticDisplayInfo.isInternal) { + double dpi; + + if (mActiveSfDisplayMode.xDpi > 0 && mActiveSfDisplayMode.yDpi > 0) { + dpi = Math.sqrt((Math.pow(mActiveSfDisplayMode.xDpi, 2) + + Math.pow(mActiveSfDisplayMode.yDpi, 2)) / 2); + } else { + // xDPI and yDPI is missing, calculate DPI from display resolution and + // default display size + dpi = Math.sqrt(Math.pow(mInfo.width, 2) + Math.pow(mInfo.height, 2)) + / DEFAULT_DISPLAY_SIZE; + } + return (int) (dpi + 0.5); + } return (int) (mStaticDisplayInfo.density * 160 + 0.5); } diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java index 0c04be10d06d..67b1ec305d7f 100644 --- a/services/core/java/com/android/server/dreams/DreamManagerService.java +++ b/services/core/java/com/android/server/dreams/DreamManagerService.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.BIND_DREAM_SERVICE; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.service.dreams.Flags.allowDreamWhenPostured; import static android.service.dreams.Flags.cleanupDreamSettingsOnUninstall; import static android.service.dreams.Flags.dreamHandlesBeingObscured; @@ -110,12 +111,13 @@ public final class DreamManagerService extends SystemService { /** Constants for the when to activate dreams. */ @Retention(RetentionPolicy.SOURCE) - @IntDef({DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_DOCK_OR_CHARGE}) + @IntDef({DREAM_DISABLED, DREAM_ON_DOCK, DREAM_ON_CHARGE, DREAM_ON_POSTURED}) public @interface WhenToDream {} - private static final int DREAM_DISABLED = 0x0; - private static final int DREAM_ON_DOCK = 0x1; - private static final int DREAM_ON_CHARGE = 0x2; - private static final int DREAM_ON_DOCK_OR_CHARGE = 0x3; + + private static final int DREAM_DISABLED = 0; + private static final int DREAM_ON_DOCK = 1 << 0; + private static final int DREAM_ON_CHARGE = 1 << 1; + private static final int DREAM_ON_POSTURED = 1 << 2; private final Object mLock = new Object(); @@ -137,6 +139,7 @@ public final class DreamManagerService extends SystemService { private final boolean mDreamsEnabledByDefaultConfig; private final boolean mDreamsActivatedOnChargeByDefault; private final boolean mDreamsActivatedOnDockByDefault; + private final boolean mDreamsActivatedOnPosturedByDefault; private final boolean mKeepDreamingWhenUnpluggingDefault; private final boolean mDreamsDisabledByAmbientModeSuppressionConfig; @@ -152,6 +155,7 @@ public final class DreamManagerService extends SystemService { @WhenToDream private int mWhenToDream; private boolean mIsDocked; private boolean mIsCharging; + private boolean mIsPostured; // A temporary dream component that, when present, takes precedence over user configured dream // component. @@ -270,6 +274,8 @@ public final class DreamManagerService extends SystemService { com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); mDreamsActivatedOnDockByDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); + mDreamsActivatedOnPosturedByDefault = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault); mSettingsObserver = new SettingsObserver(mHandler); mKeepDreamingWhenUnpluggingDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_keepDreamingWhenUnplugging); @@ -328,6 +334,9 @@ public final class DreamManagerService extends SystemService { Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), false, mSettingsObserver, UserHandle.USER_ALL); mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED), + false, mSettingsObserver, UserHandle.USER_ALL); + mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ENABLED), false, mSettingsObserver, UserHandle.USER_ALL); @@ -392,6 +401,8 @@ public final class DreamManagerService extends SystemService { pw.println("mDreamsEnabledSetting=" + mDreamsEnabledSetting); pw.println("mDreamsActivatedOnDockByDefault=" + mDreamsActivatedOnDockByDefault); pw.println("mDreamsActivatedOnChargeByDefault=" + mDreamsActivatedOnChargeByDefault); + pw.println("mDreamsActivatedOnPosturedByDefault=" + + mDreamsActivatedOnPosturedByDefault); pw.println("mIsDocked=" + mIsDocked); pw.println("mIsCharging=" + mIsCharging); pw.println("mWhenToDream=" + mWhenToDream); @@ -409,15 +420,28 @@ public final class DreamManagerService extends SystemService { synchronized (mLock) { final ContentResolver resolver = mContext.getContentResolver(); - final int activateWhenCharging = (Settings.Secure.getIntForUser(resolver, + mWhenToDream = DREAM_DISABLED; + + if ((Settings.Secure.getIntForUser(resolver, Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, mDreamsActivatedOnChargeByDefault ? 1 : 0, - UserHandle.USER_CURRENT) != 0) ? DREAM_ON_CHARGE : DREAM_DISABLED; - final int activateWhenDocked = (Settings.Secure.getIntForUser(resolver, + UserHandle.USER_CURRENT) != 0)) { + mWhenToDream |= DREAM_ON_CHARGE; + } + + if (Settings.Secure.getIntForUser(resolver, Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, mDreamsActivatedOnDockByDefault ? 1 : 0, - UserHandle.USER_CURRENT) != 0) ? DREAM_ON_DOCK : DREAM_DISABLED; - mWhenToDream = activateWhenCharging + activateWhenDocked; + UserHandle.USER_CURRENT) != 0) { + mWhenToDream |= DREAM_ON_DOCK; + } + + if (Settings.Secure.getIntForUser(resolver, + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, + mDreamsActivatedOnPosturedByDefault ? 1 : 0, + UserHandle.USER_CURRENT) != 0) { + mWhenToDream |= DREAM_ON_POSTURED; + } mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver, Settings.Secure.SCREENSAVER_ENABLED, @@ -508,6 +532,10 @@ public final class DreamManagerService extends SystemService { return mIsDocked; } + if ((mWhenToDream & DREAM_ON_POSTURED) == DREAM_ON_POSTURED) { + return mIsPostured; + } + return false; } } @@ -646,6 +674,14 @@ public final class DreamManagerService extends SystemService { } } + private void setDevicePosturedInternal(boolean isPostured) { + Slog.d(TAG, "Device postured: " + isPostured); + synchronized (mLock) { + mIsPostured = isPostured; + mHandler.post(() -> mPowerManagerInternal.setDevicePostured(isPostured)); + } + } + /** * If doze is true, returns the doze component for the user. * Otherwise, returns the system dream component, if present. @@ -1294,6 +1330,22 @@ public final class DreamManagerService extends SystemService { } } + @Override + public void setDevicePostured(boolean isPostured) { + if (!allowDreamWhenPostured()) { + return; + } + + checkPermission(android.Manifest.permission.WRITE_DREAM_STATE); + + final long ident = Binder.clearCallingIdentity(); + try { + setDevicePosturedInternal(isPostured); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + boolean canLaunchDreamActivity(String dreamPackageName, String packageName, int callingUid) { if (dreamPackageName == null || packageName == null) { diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java b/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java index ff1a74af02e2..9118c46e3b22 100644 --- a/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java +++ b/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java @@ -61,6 +61,11 @@ final class DeviceSelectActionFromTv extends HdmiCecFeatureAction { @VisibleForTesting static final int STATE_WAIT_FOR_DEVICE_POWER_ON = 3; + // State in which we wait for device to complete a possible power state change triggered by + // <Set Stream Path>. + @VisibleForTesting + static final int STATE_WAIT_FOR_POWER_STATE_CHANGE = 4; + private final HdmiDeviceInfo mTarget; private final HdmiCecMessage mGivePowerStatus; private final boolean mIsCec20; @@ -100,7 +105,12 @@ final class DeviceSelectActionFromTv extends HdmiCecFeatureAction { // Wake-up on <Set Stream Path> was not mandatory before CEC 2.0. // The message is re-sent at the end of the action for devices that don't support 2.0. sendSetStreamPath(); + mState = STATE_WAIT_FOR_POWER_STATE_CHANGE; + addTimer(mState, HdmiConfig.TIMEOUT_MS); + return true; + } + private void checkForPowerStateChange() { if (!mIsCec20) { queryDevicePowerStatus(); } else { @@ -114,12 +124,11 @@ final class DeviceSelectActionFromTv extends HdmiCecFeatureAction { queryDevicePowerStatus(); } else if (targetPowerStatus == HdmiControlManager.POWER_STATUS_ON) { finishWithCallback(HdmiControlManager.RESULT_SUCCESS); - return true; + return; } } mState = STATE_WAIT_FOR_REPORT_POWER_STATUS; addTimer(mState, HdmiConfig.TIMEOUT_MS); - return true; } private void queryDevicePowerStatus() { @@ -210,6 +219,9 @@ final class DeviceSelectActionFromTv extends HdmiCecFeatureAction { mState = STATE_WAIT_FOR_REPORT_POWER_STATUS; addTimer(mState, HdmiConfig.TIMEOUT_MS); break; + case STATE_WAIT_FOR_POWER_STATE_CHANGE: + checkForPowerStateChange(); + break; } } diff --git a/services/core/java/com/android/server/input/InputGestureManager.java b/services/core/java/com/android/server/input/InputGestureManager.java index 93fdbc787ed0..fd755e3cefe2 100644 --- a/services/core/java/com/android/server/input/InputGestureManager.java +++ b/services/core/java/com/android/server/input/InputGestureManager.java @@ -87,7 +87,20 @@ final class InputGestureManager { createKeyTrigger(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON), createKeyTrigger(KeyEvent.KEYCODE_X, KeyEvent.META_CTRL_ON), createKeyTrigger(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON), - createKeyTrigger(KeyEvent.KEYCODE_Y, KeyEvent.META_CTRL_ON) + createKeyTrigger(KeyEvent.KEYCODE_Y, KeyEvent.META_CTRL_ON), + // Used for magnification viewport control. + createKeyTrigger(KeyEvent.KEYCODE_MINUS, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON), + createKeyTrigger(KeyEvent.KEYCODE_EQUALS, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON), + createKeyTrigger(KeyEvent.KEYCODE_DPAD_LEFT, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON), + createKeyTrigger(KeyEvent.KEYCODE_DPAD_RIGHT, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON), + createKeyTrigger(KeyEvent.KEYCODE_DPAD_UP, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON), + createKeyTrigger(KeyEvent.KEYCODE_DPAD_DOWN, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON) )); public InputGestureManager(Context context) { @@ -216,24 +229,6 @@ final class InputGestureManager { systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_T, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_TALKBACK)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_MINUS, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_EQUALS, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_LEFT, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_RIGHT, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_UP, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP)); - systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_DPAD_DOWN, - KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN)); systemShortcuts.add(createKeyGesture(KeyEvent.KEYCODE_M, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_MAGNIFICATION)); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 45c7cffd462b..7b81fc92e83d 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2189,7 +2189,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. if (mVdmInternal == null) { mVdmInternal = LocalServices.getService(VirtualDeviceManagerInternal.class); } - if (mVdmInternal == null || !android.companion.virtual.flags.Flags.vdmCustomIme()) { + if (mVdmInternal == null) { return currentMethodId; } diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index 2615a76ac279..2b0ca145372b 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -334,7 +334,7 @@ public class ContextHubService extends IContextHubService.Stub { if (Flags.offloadApi() && Flags.offloadImplementation()) { HubInfoRegistry registry; try { - registry = new HubInfoRegistry(mContextHubWrapper); + registry = new HubInfoRegistry(mContext, mContextHubWrapper); mEndpointManager = new ContextHubEndpointManager( mContext, mContextHubWrapper, registry, mTransactionManager); @@ -821,6 +821,13 @@ public class ContextHubService extends IContextHubService.Stub { mHubInfoRegistry.unregisterEndpointDiscoveryCallback(callback); } + @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) + @Override + public void onDiscoveryCallbackFinished() throws RemoteException { + super.onDiscoveryCallbackFinished_enforcePermission(); + mHubInfoRegistry.onDiscoveryCallbackFinished(); + } + private void checkEndpointDiscoveryPreconditions() { if (mHubInfoRegistry == null) { Log.e(TAG, "Hub endpoint registry failed to initialize"); diff --git a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java index 6e650c207358..711383bbca37 100644 --- a/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java +++ b/services/core/java/com/android/server/location/contexthub/HubInfoRegistry.java @@ -16,12 +16,18 @@ package com.android.server.location.contexthub; +import android.content.Context; import android.hardware.contexthub.HubEndpointInfo; import android.hardware.contexthub.HubServiceInfo; import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback; import android.hardware.location.HubInfo; -import android.os.DeadObjectException; +import android.os.Binder; +import android.os.IBinder; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.os.Process; import android.os.RemoteException; +import android.os.WorkSource; import android.util.ArrayMap; import android.util.IndentingPrintWriter; import android.util.Log; @@ -30,13 +36,19 @@ import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiConsumer; class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycleCallback { private static final String TAG = "HubInfoRegistry"; + + /** The duration of wakelocks acquired during discovery callbacks */ + private static final long WAKELOCK_TIMEOUT_MILLIS = 5 * 1000; + private final Object mLock = new Object(); private final IContextHubWrapper mContextHubWrapper; @@ -52,21 +64,37 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl * A wrapper class that is used to store arguments to * ContextHubManager.registerEndpointCallback. */ - private static class DiscoveryCallback { + private static class DiscoveryCallback implements IBinder.DeathRecipient { + private final HubInfoRegistry mHubInfoRegistry; private final IContextHubEndpointDiscoveryCallback mCallback; private final Optional<Long> mEndpointId; private final Optional<String> mServiceDescriptor; - DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, long endpointId) { + // True if the binder death recipient fired + private final AtomicBoolean mBinderDied = new AtomicBoolean(false); + + DiscoveryCallback( + HubInfoRegistry registry, + IContextHubEndpointDiscoveryCallback callback, + long endpointId) + throws RemoteException { + mHubInfoRegistry = registry; mCallback = callback; mEndpointId = Optional.of(endpointId); mServiceDescriptor = Optional.empty(); + attachDeathRecipient(); } - DiscoveryCallback(IContextHubEndpointDiscoveryCallback callback, String serviceDescriptor) { + DiscoveryCallback( + HubInfoRegistry registry, + IContextHubEndpointDiscoveryCallback callback, + String serviceDescriptor) + throws RemoteException { + mHubInfoRegistry = registry; mCallback = callback; mEndpointId = Optional.empty(); mServiceDescriptor = Optional.of(serviceDescriptor); + attachDeathRecipient(); } public IContextHubEndpointDiscoveryCallback getCallback() { @@ -78,6 +106,10 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl * @return true if info matches */ public boolean isMatch(HubEndpointInfo info) { + if (mBinderDied.get()) { + Log.w(TAG, "Callback died, isMatch returning false"); + return false; + } if (mEndpointId.isPresent()) { return mEndpointId.get() == info.getIdentifier().getEndpoint(); } @@ -90,6 +122,17 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl } return false; } + + @Override + public void binderDied() { + Log.d(TAG, "Binder died for discovery callback"); + mBinderDied.set(true); + mHubInfoRegistry.unregisterEndpointDiscoveryCallback(mCallback); + } + + private void attachDeathRecipient() throws RemoteException { + mCallback.asBinder().linkToDeath(this, 0 /* flags */); + } } /* The list of discovery callbacks registered with the service */ @@ -98,7 +141,11 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl private final Object mCallbackLock = new Object(); - HubInfoRegistry(IContextHubWrapper contextHubWrapper) throws InstantiationException { + /** Wakelock held while endpoint callbacks are being invoked */ + private final WakeLock mWakeLock; + + HubInfoRegistry(Context context, IContextHubWrapper contextHubWrapper) + throws InstantiationException { mContextHubWrapper = contextHubWrapper; try { refreshCachedHubs(); @@ -108,6 +155,16 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl Log.e(TAG, error, e); throw new InstantiationException(error); } + + PowerManager powerManager = context.getSystemService(PowerManager.class); + if (powerManager == null) { + String error = "PowerManager was null"; + Log.e(TAG, error); + throw new InstantiationError(error); + } + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mWakeLock.setWorkSource(new WorkSource(Process.myUid(), context.getPackageName())); + mWakeLock.setReferenceCounted(true); } /** Retrieve the list of hubs available. */ @@ -177,12 +234,7 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl try { cb.onEndpointsStarted(infoList); } catch (RemoteException e) { - if (e instanceof DeadObjectException) { - Log.w(TAG, "onEndpointStarted: callback died, unregistering"); - unregisterEndpointDiscoveryCallback(cb); - } else { - Log.e(TAG, "Exception while calling onEndpointsStarted", e); - } + Log.e(TAG, "Exception while calling onEndpointsStarted", e); } }); } @@ -207,12 +259,7 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl cb.onEndpointsStopped( infoList, ContextHubServiceUtil.toAppHubEndpointReason(reason)); } catch (RemoteException e) { - if (e instanceof DeadObjectException) { - Log.w(TAG, "onEndpointStopped: callback died, unregistering"); - unregisterEndpointDiscoveryCallback(cb); - } else { - Log.e(TAG, "Exception while calling onEndpointsStopped", e); - } + Log.e(TAG, "Exception while calling onEndpointsStopped", e); } }); } @@ -253,7 +300,11 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl Objects.requireNonNull(callback, "callback cannot be null"); synchronized (mCallbackLock) { checkCallbackAlreadyRegistered(callback); - mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, endpointId)); + try { + mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(this, callback, endpointId)); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while adding discovery callback", e); + } } } @@ -263,7 +314,12 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl Objects.requireNonNull(callback, "callback cannot be null"); synchronized (mCallbackLock) { checkCallbackAlreadyRegistered(callback); - mEndpointDiscoveryCallbacks.add(new DiscoveryCallback(callback, serviceDescriptor)); + try { + mEndpointDiscoveryCallbacks.add( + new DiscoveryCallback(this, callback, serviceDescriptor)); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException while adding discovery callback", e); + } } } @@ -271,15 +327,21 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback) { Objects.requireNonNull(callback, "callback cannot be null"); synchronized (mCallbackLock) { - for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) { - if (discoveryCallback.getCallback().asBinder() == callback.asBinder()) { - mEndpointDiscoveryCallbacks.remove(discoveryCallback); + Iterator<DiscoveryCallback> iterator = mEndpointDiscoveryCallbacks.iterator(); + while (iterator.hasNext()) { + if (iterator.next().getCallback().asBinder() == callback.asBinder()) { + iterator.remove(); break; } } } } + /* package */ + void onDiscoveryCallbackFinished() { + releaseWakeLock(); + } + private void checkCallbackAlreadyRegistered( IContextHubEndpointDiscoveryCallback callback) { synchronized (mCallbackLock) { @@ -303,7 +365,9 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl HubEndpointInfo[] endpointInfos, BiConsumer<IContextHubEndpointDiscoveryCallback, HubEndpointInfo[]> consumer) { synchronized (mCallbackLock) { - for (DiscoveryCallback discoveryCallback : mEndpointDiscoveryCallbacks) { + Iterator<DiscoveryCallback> iterator = mEndpointDiscoveryCallbacks.iterator(); + while (iterator.hasNext()) { + DiscoveryCallback discoveryCallback = iterator.next(); ArrayList<HubEndpointInfo> infoList = new ArrayList<>(); for (HubEndpointInfo endpointInfo : endpointInfos) { if (discoveryCallback.isMatch(endpointInfo)) { @@ -311,6 +375,7 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl } } + acquireWakeLock(); consumer.accept( discoveryCallback.getCallback(), infoList.toArray(new HubEndpointInfo[infoList.size()])); @@ -318,6 +383,26 @@ class HubInfoRegistry implements ContextHubHalEndpointCallback.IEndpointLifecycl } } + private void acquireWakeLock() { + Binder.withCleanCallingIdentity( + () -> { + mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS); + }); + } + + private void releaseWakeLock() { + Binder.withCleanCallingIdentity( + () -> { + if (mWakeLock.isHeld()) { + try { + mWakeLock.release(); + } catch (RuntimeException e) { + Log.e(TAG, "Releasing the wakelock fails - ", e); + } + } + }); + } + void dump(IndentingPrintWriter ipw) { synchronized (mLock) { dumpLocked(ipw); diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java index d6f7d3bdd4a4..23e9ac5008f7 100644 --- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java +++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java @@ -545,6 +545,16 @@ final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider { for (RoutingSessionInfo session : sessions) { if (session == null) continue; session = assignProviderIdForSession(session); + + if (Flags.enableMirroringInMediaRouter2()) { + var systemSessionCallback = + mSystemSessionCallbacks.get(session.getOriginalId()); + if (systemSessionCallback != null) { + systemSessionCallback.onSessionUpdate(session); + continue; + } + } + int sourceIndex = findSessionByIdLocked(session); if (sourceIndex < 0) { mSessionInfos.add(targetIndex++, session); diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java index 8931e3a1426e..011659a616d3 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider2.java @@ -128,8 +128,20 @@ import java.util.stream.Stream; targetProviderProxyId, existingSession.getProviderId())) { // The currently selected route and target route both belong to the same // provider. We tell the provider to handle the transfer. - targetProviderProxyRecord.requestTransfer( - existingSession.getOriginalId(), serviceTargetRoute); + if (serviceTargetRoute == null) { + notifyRequestFailed( + requestId, MediaRoute2ProviderService.REASON_ROUTE_NOT_AVAILABLE); + } else { + targetProviderProxyRecord.mProxy.transferToRoute( + requestId, + clientUserHandle, + clientPackageName, + existingSession.getOriginalId(), + targetProviderProxyRecord.mNewOriginalIdToSourceOriginalIdMap.get( + routeOriginalId), + transferReason); + } + return; } else { // The target route is handled by a provider other than the target one. We need // to release the existing session. @@ -429,11 +441,6 @@ import java.util.stream.Stream; } } - public void requestTransfer(String sessionId, MediaRoute2Info targetRoute) { - // TODO: Map the target route to the source route original id. - throw new UnsupportedOperationException("TODO Implement"); - } - public void releaseSession(long requestId, String originalSessionId) { mProxy.releaseSession(requestId, originalSessionId); } @@ -491,18 +498,19 @@ import java.util.stream.Stream; () -> { if (mSessionRecord != null) { mSessionRecord.onSessionUpdate(sessionInfo); + } else { + SystemMediaSessionRecord systemMediaSessionRecord = + new SystemMediaSessionRecord(mProviderId, sessionInfo); + RoutingSessionInfo translatedSession; + synchronized (mLock) { + mSessionRecord = systemMediaSessionRecord; + mPackageNameToSessionRecord.put( + mClientPackageName, systemMediaSessionRecord); + mPendingSessionCreations.remove(mRequestId); + translatedSession = systemMediaSessionRecord.mTranslatedSessionInfo; + } + onSessionOverrideUpdated(translatedSession); } - SystemMediaSessionRecord systemMediaSessionRecord = - new SystemMediaSessionRecord(mProviderId, sessionInfo); - RoutingSessionInfo translatedSession; - synchronized (mLock) { - mSessionRecord = systemMediaSessionRecord; - mPackageNameToSessionRecord.put( - mClientPackageName, systemMediaSessionRecord); - mPendingSessionCreations.remove(mRequestId); - translatedSession = systemMediaSessionRecord.mTranslatedSessionInfo; - } - onSessionOverrideUpdated(translatedSession); }); } @@ -546,7 +554,6 @@ import java.util.stream.Stream; * The same as {@link #mSourceSessionInfo}, except ids are {@link #asSystemRouteId system * provider ids}. */ - @GuardedBy("SystemMediaRoute2Provider2.this.mLock") @NonNull private RoutingSessionInfo mTranslatedSessionInfo; @@ -559,10 +566,10 @@ import java.util.stream.Stream; @Override public void onSessionUpdate(@NonNull RoutingSessionInfo sessionInfo) { - RoutingSessionInfo translatedSessionInfo = mTranslatedSessionInfo; + RoutingSessionInfo translatedSessionInfo = asSystemProviderSession(sessionInfo); synchronized (mLock) { mSourceSessionInfo = sessionInfo; - mTranslatedSessionInfo = asSystemProviderSession(sessionInfo); + mTranslatedSessionInfo = translatedSessionInfo; } onSessionOverrideUpdated(translatedSessionInfo); } diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java index efc1b9959c0f..e47cbdc3546f 100644 --- a/services/core/java/com/android/server/media/quality/MediaQualityService.java +++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java @@ -16,18 +16,33 @@ package com.android.server.media.quality; +import static android.media.quality.AmbientBacklightEvent.AMBIENT_BACKLIGHT_EVENT_ENABLED; +import static android.media.quality.AmbientBacklightEvent.AMBIENT_BACKLIGHT_EVENT_DISABLED; +import static android.media.quality.AmbientBacklightEvent.AMBIENT_BACKLIGHT_EVENT_METADATA_AVAILABLE; +import static android.media.quality.AmbientBacklightEvent.AMBIENT_BACKLIGHT_EVENT_INTERRUPTED; + +import android.annotation.NonNull; import android.content.ContentValues; import android.content.Context; import android.content.pm.PackageManager; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.hardware.tv.mediaquality.AmbientBacklightColorFormat; import android.hardware.tv.mediaquality.IMediaQuality; +import android.hardware.tv.mediaquality.PictureParameter; +import android.hardware.tv.mediaquality.PictureParameters; +import android.hardware.tv.mediaquality.SoundParameter; +import android.hardware.tv.mediaquality.SoundParameters; +import android.media.quality.AmbientBacklightEvent; +import android.media.quality.AmbientBacklightMetadata; import android.media.quality.AmbientBacklightSettings; import android.media.quality.IAmbientBacklightCallback; import android.media.quality.IMediaQualityManager; import android.media.quality.IPictureProfileCallback; import android.media.quality.ISoundProfileCallback; import android.media.quality.MediaQualityContract.BaseParameters; +import android.media.quality.MediaQualityContract.PictureQuality; +import android.media.quality.MediaQualityContract.SoundQuality; import android.media.quality.MediaQualityManager; import android.media.quality.ParameterCapability; import android.media.quality.PictureProfile; @@ -42,6 +57,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.util.Slog; @@ -60,6 +76,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.UUID; import java.util.stream.Collectors; @@ -76,13 +93,16 @@ public class MediaQualityService extends SystemService { private final MediaQualityDbHelper mMediaQualityDbHelper; private final BiMap<Long, String> mPictureProfileTempIdMap; private final BiMap<Long, String> mSoundProfileTempIdMap; + private IMediaQuality mMediaQuality; + private final HalAmbientBacklightCallback mHalAmbientBacklightCallback; + private final Map<String, AmbientBacklightCallbackRecord> mCallbackRecords = new HashMap<>(); private final PackageManager mPackageManager; private final SparseArray<UserState> mUserStates = new SparseArray<>(); - private IMediaQuality mMediaQuality; public MediaQualityService(Context context) { super(context); mContext = context; + mHalAmbientBacklightCallback = new HalAmbientBacklightCallback(); mPackageManager = mContext.getPackageManager(); mPictureProfileTempIdMap = new BiMap<>(); mSoundProfileTempIdMap = new BiMap<>(); @@ -97,6 +117,13 @@ public class MediaQualityService extends SystemService { if (binder != null) { Slogf.d(TAG, "binder is not null"); mMediaQuality = IMediaQuality.Stub.asInterface(binder); + if (mMediaQuality != null) { + try { + mMediaQuality.setAmbientBacklightCallback(mHalAmbientBacklightCallback); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set ambient backlight detector callback", e); + } + } } publishBinderService(Context.MEDIA_QUALITY_SERVICE, new BinderService()); @@ -282,10 +309,208 @@ public class MediaQualityService extends SystemService { notifyOnPictureProfileError(profileId, PictureProfile.ERROR_NO_PERMISSION, Binder.getCallingUid(), Binder.getCallingPid()); } - // TODO: pass the profile ID to MediaQuality HAL when ready. + + PictureProfile pictureProfile = getPictureProfile( + mPictureProfileTempIdMap.getKey(profileId)); + PersistableBundle params = pictureProfile.getParameters(); + + try { + if (mMediaQuality != null) { + PictureParameter[] pictureParameters = + convertPersistableBundleToPictureParameterList(params); + + PictureParameters pp = new PictureParameters(); + pp.pictureParameters = pictureParameters; + + mMediaQuality.sendDefaultPictureParameters(pp); + return true; + } + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set default picture profile", e); + } return false; } + private PictureParameter[] convertPersistableBundleToPictureParameterList( + PersistableBundle params) { + List<PictureParameter> pictureParams = new ArrayList<>(); + if (params.containsKey(PictureQuality.PARAMETER_BRIGHTNESS)) { + pictureParams.add(PictureParameter.brightness(params.getLong( + PictureQuality.PARAMETER_BRIGHTNESS))); + } + if (params.containsKey(PictureQuality.PARAMETER_CONTRAST)) { + pictureParams.add(PictureParameter.contrast(params.getInt( + PictureQuality.PARAMETER_CONTRAST))); + } + if (params.containsKey(PictureQuality.PARAMETER_SHARPNESS)) { + pictureParams.add(PictureParameter.sharpness(params.getInt( + PictureQuality.PARAMETER_SHARPNESS))); + } + if (params.containsKey(PictureQuality.PARAMETER_SATURATION)) { + pictureParams.add(PictureParameter.saturation(params.getInt( + PictureQuality.PARAMETER_SATURATION))); + } + if (params.containsKey(PictureQuality.PARAMETER_HUE)) { + pictureParams.add(PictureParameter.hue(params.getInt( + PictureQuality.PARAMETER_HUE))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS)) { + pictureParams.add(PictureParameter.colorTunerBrightness(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION)) { + pictureParams.add(PictureParameter.colorTunerSaturation(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_SATURATION))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE)) { + pictureParams.add(PictureParameter.colorTunerHue(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_HUE))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET)) { + pictureParams.add(PictureParameter.colorTunerRedOffset(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET)) { + pictureParams.add(PictureParameter.colorTunerGreenOffset(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET)) { + pictureParams.add(PictureParameter.colorTunerBlueOffset(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) { + pictureParams.add(PictureParameter.colorTunerRedGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) { + pictureParams.add(PictureParameter.colorTunerGreenGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) { + pictureParams.add(PictureParameter.colorTunerBlueGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN))); + } + if (params.containsKey(PictureQuality.PARAMETER_NOISE_REDUCTION)) { + pictureParams.add(PictureParameter.noiseReduction( + (byte) params.getInt(PictureQuality.PARAMETER_NOISE_REDUCTION))); + } + if (params.containsKey(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION)) { + pictureParams.add(PictureParameter.mpegNoiseReduction( + (byte) params.getInt(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION))); + } + if (params.containsKey(PictureQuality.PARAMETER_FLESH_TONE)) { + pictureParams.add(PictureParameter.fleshTone( + (byte) params.getInt(PictureQuality.PARAMETER_FLESH_TONE))); + } + if (params.containsKey(PictureQuality.PARAMETER_DECONTOUR)) { + pictureParams.add(PictureParameter.deContour( + (byte) params.getInt(PictureQuality.PARAMETER_DECONTOUR))); + } + if (params.containsKey(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL)) { + pictureParams.add(PictureParameter.dynamicLumaControl( + (byte) params.getInt(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL))); + } + if (params.containsKey(PictureQuality.PARAMETER_FILM_MODE)) { + pictureParams.add(PictureParameter.filmMode(params.getBoolean( + PictureQuality.PARAMETER_FILM_MODE))); + } + if (params.containsKey(PictureQuality.PARAMETER_BLUE_STRETCH)) { + pictureParams.add(PictureParameter.blueStretch(params.getBoolean( + PictureQuality.PARAMETER_BLUE_STRETCH))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNE)) { + pictureParams.add(PictureParameter.colorTune(params.getBoolean( + PictureQuality.PARAMETER_COLOR_TUNE))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE)) { + pictureParams.add(PictureParameter.colorTemperature( + (byte) params.getInt( + PictureQuality.PARAMETER_COLOR_TEMPERATURE))); + } + if (params.containsKey(PictureQuality.PARAMETER_GLOBAL_DIMMING)) { + pictureParams.add(PictureParameter.globeDimming(params.getBoolean( + PictureQuality.PARAMETER_GLOBAL_DIMMING))); + } + if (params.containsKey(PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED)) { + pictureParams.add(PictureParameter.autoPictureQualityEnabled(params.getBoolean( + PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED))); + } + if (params.containsKey(PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED)) { + pictureParams.add(PictureParameter.autoSuperResolutionEnabled(params.getBoolean( + PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) { + pictureParams.add(PictureParameter.colorTemperatureRedGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) { + pictureParams.add(PictureParameter.colorTemperatureGreenGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN))); + } + if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) { + pictureParams.add(PictureParameter.colorTemperatureBlueGain(params.getInt( + PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN))); + } + + /** + * TODO: add conversion for following after adding to MediaQualityContract + * + * PictureParameter.levelRange + * PictureParameter.gamutMapping + * PictureParameter.pcMode + * PictureParameter.lowLatency + * PictureParameter.vrr + * PictureParameter.cvrr + * PictureParameter.hdmiRgbRange + * PictureParameter.colorSpace + * PictureParameter.panelInitMaxLuminceNits + * PictureParameter.panelInitMaxLuminceValid + * PictureParameter.gamma + * PictureParameter.colorTemperatureRedOffset + * PictureParameter.colorTemperatureGreenOffset + * PictureParameter.colorTemperatureBlueOffset + * PictureParameter.elevenPointRed + * PictureParameter.elevenPointGreen + * PictureParameter.elevenPointBlue + * PictureParameter.lowBlueLight + * PictureParameter.LdMode + * PictureParameter.osdRedGain + * PictureParameter.osdGreenGain + * PictureParameter.osdBlueGain + * PictureParameter.osdRedOffset + * PictureParameter.osdGreenOffset + * PictureParameter.osdBlueOffset + * PictureParameter.osdHue + * PictureParameter.osdSaturation + * PictureParameter.osdContrast + * PictureParameter.colorTunerSwitch + * PictureParameter.colorTunerHueRed + * PictureParameter.colorTunerHueGreen + * PictureParameter.colorTunerHueBlue + * PictureParameter.colorTunerHueCyan + * PictureParameter.colorTunerHueMagenta + * PictureParameter.colorTunerHueYellow + * PictureParameter.colorTunerHueFlesh + * PictureParameter.colorTunerSaturationRed + * PictureParameter.colorTunerSaturationGreen + * PictureParameter.colorTunerSaturationBlue + * PictureParameter.colorTunerSaturationCyan + * PictureParameter.colorTunerSaturationMagenta + * PictureParameter.colorTunerSaturationYellow + * PictureParameter.colorTunerSaturationFlesh + * PictureParameter.colorTunerLuminanceRed + * PictureParameter.colorTunerLuminanceGreen + * PictureParameter.colorTunerLuminanceBlue + * PictureParameter.colorTunerLuminanceCyan + * PictureParameter.colorTunerLuminanceMagenta + * PictureParameter.colorTunerLuminanceYellow + * PictureParameter.colorTunerLuminanceFlesh + * PictureParameter.activeProfile + * PictureParameter.pictureQualityEventType + */ + return (PictureParameter[]) pictureParams.toArray(); + } + @Override public List<String> getPictureProfilePackageNames(UserHandle user) { if (!hasGlobalPictureQualityServicePermission()) { @@ -503,10 +728,77 @@ public class MediaQualityService extends SystemService { notifyOnSoundProfileError(profileId, SoundProfile.ERROR_NO_PERMISSION, Binder.getCallingUid(), Binder.getCallingPid()); } - // TODO: pass the profile ID to MediaQuality HAL when ready. + + SoundProfile soundProfile = getSoundProfile(mSoundProfileTempIdMap.getKey(profileId)); + PersistableBundle params = soundProfile.getParameters(); + + try { + if (mMediaQuality != null) { + SoundParameter[] soundParameters = + convertPersistableBundleToSoundParameterList(params); + + SoundParameters sp = new SoundParameters(); + sp.soundParameters = soundParameters; + + mMediaQuality.sendDefaultSoundParameters(sp); + return true; + } + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set default sound profile", e); + } return false; } + private SoundParameter[] convertPersistableBundleToSoundParameterList( + PersistableBundle params) { + List<SoundParameter> soundParams = new ArrayList<>(); + if (params.containsKey(SoundQuality.PARAMETER_BALANCE)) { + soundParams.add(SoundParameter.balance(params.getInt( + SoundQuality.PARAMETER_BALANCE))); + } + if (params.containsKey(SoundQuality.PARAMETER_BASS)) { + soundParams.add(SoundParameter.bass(params.getInt(SoundQuality.PARAMETER_BASS))); + } + if (params.containsKey(SoundQuality.PARAMETER_TREBLE)) { + soundParams.add(SoundParameter.treble(params.getInt( + SoundQuality.PARAMETER_TREBLE))); + } + if (params.containsKey(SoundQuality.PARAMETER_SURROUND_SOUND)) { + soundParams.add(SoundParameter.surroundSoundEnabled(params.getBoolean( + SoundQuality.PARAMETER_SURROUND_SOUND))); + } + if (params.containsKey(SoundQuality.PARAMETER_SPEAKERS)) { + soundParams.add(SoundParameter.speakersEnabled(params.getBoolean( + SoundQuality.PARAMETER_SPEAKERS))); + } + if (params.containsKey(SoundQuality.PARAMETER_SPEAKERS_DELAY_MILLIS)) { + soundParams.add(SoundParameter.speakersDelayMs(params.getInt( + SoundQuality.PARAMETER_SPEAKERS_DELAY_MILLIS))); + } + if (params.containsKey(SoundQuality.PARAMETER_AUTO_VOLUME_CONTROL)) { + soundParams.add(SoundParameter.autoVolumeControl(params.getBoolean( + SoundQuality.PARAMETER_AUTO_VOLUME_CONTROL))); + } + if (params.containsKey(SoundQuality.PARAMETER_DTS_DRC)) { + soundParams.add(SoundParameter.dtsDrc(params.getBoolean( + SoundQuality.PARAMETER_DTS_DRC))); + } + if (params.containsKey(SoundQuality.PARAMETER_DIGITAL_OUTPUT_DELAY_MILLIS)) { + soundParams.add(SoundParameter.surroundSoundEnabled(params.getBoolean( + SoundQuality.PARAMETER_DIGITAL_OUTPUT_DELAY_MILLIS))); + } + //TODO: equalizerDetail + //TODO: downmixMode + //TODO: enhancedAudioReturnChannelEnabled + //TODO: dolbyAudioProcessing + //TODO: dolbyDialogueEnhancer + //TODO: dtsVirtualX + //TODO: digitalOutput + //TODO: activeProfile + //TODO: soundStyle + return (SoundParameter[]) soundParams.toArray(); + } + @Override public List<String> getSoundProfilePackageNames(UserHandle user) { if (!hasGlobalSoundQualityServicePermission()) { @@ -905,24 +1197,86 @@ public class MediaQualityService extends SystemService { @Override public void registerAmbientBacklightCallback(IAmbientBacklightCallback callback) { + if (DEBUG) { + Slogf.d(TAG, "registerAmbientBacklightCallback"); + } + if (!hasReadColorZonesPermission()) { //TODO: error handling } + + String callingPackageName = getPackageOfCallingUid(); + + synchronized (mCallbackRecords) { + AmbientBacklightCallbackRecord record = mCallbackRecords.get(callingPackageName); + if (record != null) { + if (record.mCallback.asBinder().equals(callback.asBinder())) { + Slog.w(TAG, "AmbientBacklight Callback already registered"); + return; + } + record.release(); + mCallbackRecords.remove(callingPackageName); + } + mCallbackRecords.put(callingPackageName, + new AmbientBacklightCallbackRecord(callingPackageName, callback)); + } } @Override public void setAmbientBacklightSettings( AmbientBacklightSettings settings, UserHandle user) { + if (DEBUG) { + Slogf.d(TAG, "setAmbientBacklightSettings " + settings); + } + if (!hasReadColorZonesPermission()) { //TODO: error handling } + + try { + if (mMediaQuality != null) { + android.hardware.tv.mediaquality.AmbientBacklightSettings halSettings = + new android.hardware.tv.mediaquality.AmbientBacklightSettings(); + halSettings.uid = Binder.getCallingUid(); + halSettings.source = (byte) settings.getSource(); + halSettings.maxFramerate = settings.getMaxFps(); + halSettings.colorFormat = (byte) settings.getColorFormat(); + halSettings.hZonesNumber = settings.getHorizontalZonesCount(); + halSettings.vZonesNumber = settings.getVerticalZonesCount(); + halSettings.hasLetterbox = settings.isLetterboxOmitted(); + halSettings.colorThreshold = settings.getThreshold(); + + mMediaQuality.setAmbientBacklightDetector(halSettings); + + mHalAmbientBacklightCallback.setAmbientBacklightClientPackageName( + getPackageOfCallingUid()); + + if (DEBUG) { + Slogf.d(TAG, "set ambient settings package: " + halSettings.uid); + } + } + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set ambient backlight settings", e); + } } @Override public void setAmbientBacklightEnabled(boolean enabled, UserHandle user) { + if (DEBUG) { + Slogf.d(TAG, "setAmbientBacklightEnabled " + enabled); + } if (!hasReadColorZonesPermission()) { //TODO: error handling } + try { + if (mMediaQuality != null) { + mMediaQuality.setAmbientBacklightDetectionEnabled(enabled); + } + } catch (UnsupportedOperationException e) { + Slog.e(TAG, "The current device is not supported"); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to set ambient backlight enabled", e); + } } @Override @@ -979,10 +1333,10 @@ public class MediaQualityService extends SystemService { try { if (mMediaQuality != null) { - mMediaQuality.setAutoPqEnabled(enabled); + if (mMediaQuality.isAutoPqSupported()) { + mMediaQuality.setAutoPqEnabled(enabled); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { Slog.e(TAG, "Failed to set auto picture quality", e); } @@ -992,10 +1346,10 @@ public class MediaQualityService extends SystemService { public boolean isAutoPictureQualityEnabled(UserHandle user) { try { if (mMediaQuality != null) { - return mMediaQuality.getAutoPqEnabled(); + if (mMediaQuality.isAutoPqSupported()) { + mMediaQuality.getAutoPqEnabled(); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { Slog.e(TAG, "Failed to get auto picture quality", e); } @@ -1011,12 +1365,12 @@ public class MediaQualityService extends SystemService { try { if (mMediaQuality != null) { - mMediaQuality.setAutoSrEnabled(enabled); + if (mMediaQuality.isAutoSrSupported()) { + mMediaQuality.setAutoSrEnabled(enabled); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { - Slog.e(TAG, "Failed to set auto super resolution", e); + Slog.e(TAG, "Failed to set super resolution", e); } } @@ -1024,12 +1378,12 @@ public class MediaQualityService extends SystemService { public boolean isSuperResolutionEnabled(UserHandle user) { try { if (mMediaQuality != null) { - return mMediaQuality.getAutoSrEnabled(); + if (mMediaQuality.isAutoSrSupported()) { + mMediaQuality.getAutoSrEnabled(); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { - Slog.e(TAG, "Failed to get auto super resolution", e); + Slog.e(TAG, "Failed to get super resolution", e); } return false; } @@ -1043,12 +1397,12 @@ public class MediaQualityService extends SystemService { try { if (mMediaQuality != null) { - mMediaQuality.setAutoAqEnabled(enabled); + if (mMediaQuality.isAutoAqSupported()) { + mMediaQuality.setAutoAqEnabled(enabled); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { - Slog.e(TAG, "Failed to set auto audio quality", e); + Slog.e(TAG, "Failed to set auto sound quality", e); } } @@ -1056,12 +1410,12 @@ public class MediaQualityService extends SystemService { public boolean isAutoSoundQualityEnabled(UserHandle user) { try { if (mMediaQuality != null) { - return mMediaQuality.getAutoAqEnabled(); + if (mMediaQuality.isAutoAqSupported()) { + mMediaQuality.getAutoAqEnabled(); + } } - } catch (UnsupportedOperationException e) { - Slog.e(TAG, "The current device is not supported"); } catch (RemoteException e) { - Slog.e(TAG, "Failed to get auto audio quality", e); + Slog.e(TAG, "Failed to get auto sound quality", e); } return false; } @@ -1119,4 +1473,167 @@ public class MediaQualityService extends SystemService { private UserState getUserStateLocked(int userId) { return mUserStates.get(userId); } + + private final class AmbientBacklightCallbackRecord implements IBinder.DeathRecipient { + final String mPackageName; + final IAmbientBacklightCallback mCallback; + + AmbientBacklightCallbackRecord(@NonNull String pkgName, + @NonNull IAmbientBacklightCallback cb) { + mPackageName = pkgName; + mCallback = cb; + try { + mCallback.asBinder().linkToDeath(this, 0); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to link to death", e); + } + } + + void release() { + try { + mCallback.asBinder().unlinkToDeath(this, 0); + } catch (NoSuchElementException e) { + Slog.e(TAG, "Failed to unlink to death", e); + } + } + + @Override + public void binderDied() { + synchronized (mCallbackRecords) { + mCallbackRecords.remove(mPackageName); + } + } + } + + private final class HalAmbientBacklightCallback + extends android.hardware.tv.mediaquality.IMediaQualityCallback.Stub { + private final Object mLock = new Object(); + private String mAmbientBacklightClientPackageName; + + void setAmbientBacklightClientPackageName(@NonNull String packageName) { + synchronized (mLock) { + if (TextUtils.equals(mAmbientBacklightClientPackageName, packageName)) { + return; + } + handleAmbientBacklightInterrupted(); + mAmbientBacklightClientPackageName = packageName; + } + } + + void handleAmbientBacklightInterrupted() { + synchronized (mCallbackRecords) { + if (mAmbientBacklightClientPackageName == null) { + Slog.e(TAG, "Invalid package name in interrupted event"); + return; + } + AmbientBacklightCallbackRecord record = mCallbackRecords.get( + mAmbientBacklightClientPackageName); + if (record == null) { + Slog.e(TAG, "Callback record not found for ambient backlight"); + return; + } + AmbientBacklightEvent event = + new AmbientBacklightEvent( + AMBIENT_BACKLIGHT_EVENT_INTERRUPTED, null); + try { + record.mCallback.onAmbientBacklightEvent(event); + } catch (RemoteException e) { + Slog.e(TAG, "Deliver ambient backlight interrupted event failed", e); + } + } + } + + void handleAmbientBacklightEnabled(boolean enabled) { + AmbientBacklightEvent event = + new AmbientBacklightEvent( + enabled ? AMBIENT_BACKLIGHT_EVENT_ENABLED : + AMBIENT_BACKLIGHT_EVENT_DISABLED, null); + synchronized (mCallbackRecords) { + for (AmbientBacklightCallbackRecord record : mCallbackRecords.values()) { + try { + record.mCallback.onAmbientBacklightEvent(event); + } catch (RemoteException e) { + Slog.e(TAG, "Deliver ambient backlight enabled event failed", e); + } + } + } + } + + void handleAmbientBacklightMetadataEvent( + @NonNull android.hardware.tv.mediaquality.AmbientBacklightMetadata + halMetadata) { + String halPackageName = mContext.getPackageManager() + .getNameForUid(halMetadata.settings.uid); + if (!TextUtils.equals(mAmbientBacklightClientPackageName, halPackageName)) { + Slog.e(TAG, "Invalid package name in metadata event"); + return; + } + + AmbientBacklightColorFormat[] zonesColorsUnion = halMetadata.zonesColors; + int[] zonesColorsInt = new int[zonesColorsUnion.length]; + + for (int i = 0; i < zonesColorsUnion.length; i++) { + zonesColorsInt[i] = zonesColorsUnion[i].RGB888; + } + + AmbientBacklightMetadata metadata = + new AmbientBacklightMetadata( + halPackageName, + halMetadata.compressAlgorithm, + halMetadata.settings.source, + halMetadata.settings.colorFormat, + halMetadata.settings.hZonesNumber, + halMetadata.settings.vZonesNumber, + zonesColorsInt); + AmbientBacklightEvent event = + new AmbientBacklightEvent( + AMBIENT_BACKLIGHT_EVENT_METADATA_AVAILABLE, metadata); + + synchronized (mCallbackRecords) { + AmbientBacklightCallbackRecord record = mCallbackRecords + .get(halPackageName); + if (record == null) { + Slog.e(TAG, "Callback record not found for ambient backlight metadata"); + return; + } + + try { + record.mCallback.onAmbientBacklightEvent(event); + } catch (RemoteException e) { + Slog.e(TAG, "Deliver ambient backlight metadata event failed", e); + } + } + } + + @Override + public void notifyAmbientBacklightEvent( + android.hardware.tv.mediaquality.AmbientBacklightEvent halEvent) { + synchronized (mLock) { + if (halEvent.getTag() == android.hardware.tv.mediaquality + .AmbientBacklightEvent.Tag.enabled) { + boolean enabled = halEvent.getEnabled(); + if (enabled) { + handleAmbientBacklightEnabled(true); + } else { + handleAmbientBacklightEnabled(false); + } + } else if (halEvent.getTag() == android.hardware.tv.mediaquality + .AmbientBacklightEvent.Tag.metadata) { + handleAmbientBacklightMetadataEvent(halEvent.getMetadata()); + } else { + Slog.e(TAG, "Invalid event type in ambient backlight event"); + } + } + } + + @Override + public synchronized String getInterfaceHash() throws android.os.RemoteException { + return android.hardware.tv.mediaquality.IMediaQualityCallback.Stub.HASH; + } + + @Override + public int getInterfaceVersion() throws android.os.RemoteException { + return android.hardware.tv.mediaquality.IMediaQualityCallback.Stub.VERSION; + } + } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f3eed7d22bec..ef39f1811876 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -27,6 +27,7 @@ import static android.app.AppOpsManager.OP_RECEIVE_SENSITIVE_NOTIFICATIONS; import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR; import static android.app.Flags.lifetimeExtensionRefactor; import static android.app.Flags.notificationClassificationUi; +import static android.app.Flags.redactSensitiveContentNotificationsOnLockscreen; import static android.app.Flags.sortSectionByTime; import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION; import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO; @@ -254,6 +255,10 @@ import android.content.pm.VersionedPackage; import android.content.res.Resources; import android.database.ContentObserver; import android.metrics.LogMaker; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -656,6 +661,7 @@ public class NotificationManagerService extends SystemService { private UsageStatsManagerInternal mUsageStatsManagerInternal; private TelecomManager mTelecomManager; private PowerManager mPowerManager; + private ConnectivityManager mConnectivityManager; private PostNotificationTrackerFactory mPostNotificationTrackerFactory; private LockPatternUtils mLockUtils; @@ -756,6 +762,7 @@ public class NotificationManagerService extends SystemService { private int mWarnRemoteViewsSizeBytes; private int mStripRemoteViewsSizeBytes; + private String[] mDefaultUnsupportedAdjustments; @VisibleForTesting protected boolean mShowReviewPermissionsNotification; @@ -777,6 +784,8 @@ public class NotificationManagerService extends SystemService { private ModuleInfo mAdservicesModuleInfo; + private boolean mConnectedToWifi; + static class Archive { final SparseArray<Boolean> mEnabled; final int mBufferSize; @@ -2573,6 +2582,7 @@ public class NotificationManagerService extends SystemService { TelecomManager telecomManager, NotificationChannelLogger channelLogger, SystemUiSystemPropertiesFlags.FlagResolver flagResolver, PermissionManager permissionManager, PowerManager powerManager, + ConnectivityManager connectivityManager, PostNotificationTrackerFactory postNotificationTrackerFactory) { mHandler = handler; Resources resources = getContext().getResources(); @@ -2605,6 +2615,8 @@ public class NotificationManagerService extends SystemService { mUm = userManager; mTelecomManager = telecomManager; mPowerManager = powerManager; + mConnectivityManager = connectivityManager; + registerNetworkCallback(); mPostNotificationTrackerFactory = postNotificationTrackerFactory; mPlatformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); @@ -2820,6 +2832,36 @@ public class NotificationManagerService extends SystemService { mAppOps.startWatchingMode(AppOpsManager.OP_POST_NOTIFICATION, null, mAppOpsListener); } + private void registerNetworkCallback() { + NetworkRequest request = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI).build(); + mConnectivityManager.registerNetworkCallback(request, + new ConnectivityManager.NetworkCallback() { + // Need to post to another thread, as we can't call synchronous ConnectivityManager + // methods from the callback itself, due to potential race conditions. + @Override + public void onAvailable(@NonNull Network network) { + mHandler.post(() -> updateWifiConnectionState()); + } + @Override + public void onLost(@NonNull Network network) { + mHandler.post(() -> updateWifiConnectionState()); + } + }); + updateWifiConnectionState(); + } + + @VisibleForTesting() + void updateWifiConnectionState() { + Network current = mConnectivityManager.getActiveNetwork(); + NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(current); + if (current == null || capabilities == null) { + mConnectedToWifi = false; + return; + } + mConnectedToWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); + } + /** * Cleanup broadcast receivers change listeners. */ @@ -2897,6 +2939,9 @@ public class NotificationManagerService extends SystemService { mShowReviewPermissionsNotification = getContext().getResources().getBoolean( R.bool.config_notificationReviewPermissions); + mDefaultUnsupportedAdjustments = getContext().getResources().getStringArray( + R.array.config_notificationDefaultUnsupportedAdjustments); + init(handler, new RankingHandlerWorker(mRankingThread.getLooper()), AppGlobals.getPackageManager(), getContext().getPackageManager(), getLocalService(LightsManager.class), @@ -2930,6 +2975,7 @@ public class NotificationManagerService extends SystemService { new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(), getContext().getSystemService(PermissionManager.class), getContext().getSystemService(PowerManager.class), + getContext().getSystemService(ConnectivityManager.class), new PostNotificationTrackerFactory() {}); publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false, @@ -2991,10 +3037,9 @@ public class NotificationManagerService extends SystemService { switch(atomTag) { case PACKAGE_NOTIFICATION_PREFERENCES: if (notificationClassificationUi()) { - Set<String> pkgs = mAssistants.getPackagesWithKeyTypeAdjustmentSettings(); mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions(), - getPackageSpecificAdjustmentKeyTypes(pkgs)); + new ArrayMap<>()); } else { mPreferencesHelper.pullPackagePreferencesStats(data, getAllUsersNotificationPermissions()); @@ -4355,16 +4400,16 @@ public class NotificationManagerService extends SystemService { @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { + public @NonNull String[] getTypeAdjustmentDeniedPackages() { checkCallerIsSystemOrSystemUiOrShell(); - return mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); + return mAssistants.getTypeAdjustmentDeniedPackages(); } + @Override @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, int type, - boolean enabled) { + public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { checkCallerIsSystemOrSystemUiOrShell(); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, type, enabled); + mAssistants.setTypeAdjustmentForPackageState(pkg, enabled); handleSavePolicyFile(); } @@ -7173,7 +7218,7 @@ public class NotificationManagerService extends SystemService { toRemove.add(potentialKey); } else if (notificationClassificationUi() && !mAssistants.isTypeAdjustmentAllowedForPackage( - r.getSbn().getPackageName(), adjustments.getInt(KEY_TYPE))) { + r.getSbn().getPackageName())) { toRemove.add(potentialKey); } } @@ -7510,24 +7555,6 @@ public class NotificationManagerService extends SystemService { return allPermissions; } - @VisibleForTesting - @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - protected @NonNull Map<String, Set<Integer>> getPackageSpecificAdjustmentKeyTypes( - Set<String> pkgs) { - ArrayMap<String, Set<Integer>> pkgToAllowedTypes = new ArrayMap<>(); - for (String pkg : pkgs) { - int[] allowedTypesArray = mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg); - if (allowedTypesArray != null) { - Set<Integer> allowedTypes = new ArraySet<Integer>(); - for (int i : allowedTypesArray) { - allowedTypes.add(i); - } - pkgToAllowedTypes.append(pkg, allowedTypes); - } - } - return pkgToAllowedTypes; - } - private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter, ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) { JSONObject dump = new JSONObject(); @@ -11645,12 +11672,20 @@ public class NotificationManagerService extends SystemService { new NotificationListenerService.Ranking(); ArrayList<Notification.Action> smartActions = record.getSystemGeneratedSmartActions(); ArrayList<CharSequence> smartReplies = record.getSmartReplies(); - if (redactSensitiveNotificationsFromUntrustedListeners() - && info != null - && !mListeners.isUidTrusted(info.uid) - && mListeners.hasSensitiveContent(record)) { - smartActions = null; - smartReplies = null; + boolean hasSensitiveContent = record.hasSensitiveContent(); + if (redactSensitiveNotificationsFromUntrustedListeners()) { + if (!mListeners.isUidTrusted(info.uid) && mListeners.hasSensitiveContent(record)) { + smartActions = null; + smartReplies = null; + } + if (redactSensitiveContentNotificationsOnLockscreen()) { + if (mListeners.hasSensitiveContent(record) && mConnectedToWifi + && info.isSystemUi) { + // We don't inform systemUI of sensitive content if + // connected to wifi, though we do still redact from untrusted listeners. + hasSensitiveContent = false; + } + } } ranking.populate( key, @@ -11680,7 +11715,7 @@ public class NotificationManagerService extends SystemService { : (record.getRankingScore() > 0 ? RANKING_PROMOTED : RANKING_DEMOTED), record.getNotification().isBubbleNotification(), record.getProposedImportance(), - record.hasSensitiveContent() + hasSensitiveContent ); rankings.add(ranking); } @@ -11835,11 +11870,7 @@ public class NotificationManagerService extends SystemService { private static final String ATT_DENIED = "denied_adjustments"; private static final String ATT_ENABLED_TYPES = "enabled_key_types"; private static final String ATT_NAS_UNSUPPORTED = "unsupported_adjustments"; - // Encapsulates a list of packages and the bundle types enabled for each package. - private static final String TAG_TYPES_ENABLED_FOR_APPS = "types_enabled_for_apps"; - // Encapsulates the bundle types enabled for a package. - private static final String ATT_APP_ENABLED_TYPES = "app_enabled_types"; - private static final String ATT_PACKAGE = "package"; + private static final String ATT_TYPES_DENIED_APPS = "types_denied_apps"; private final Object mLock = new Object(); @@ -11855,14 +11886,8 @@ public class NotificationManagerService extends SystemService { @GuardedBy("mLock") private Map<Integer, HashSet<String>> mNasUnsupported = new ArrayMap<>(); - // Types of classifications (aka bundles) enabled/allowed for this package. - // If the set is NULL (or package is not in the list), default classification allow list - // (the global one) should be used. - // If the set is empty, that indicates the package explicitly has all classifications - // disallowed. @GuardedBy("mLock") - private Map<String, Set<Integer>> mClassificationTypePackagesEnabledTypes = - new ArrayMap<>(); + private Set<String> mClassificationTypeDeniedPackages = new ArraySet<>(); protected ComponentName mDefaultFromConfig = null; @@ -11940,6 +11965,9 @@ public class NotificationManagerService extends SystemService { } } else { mAllowedAdjustmentKeyTypes.addAll(List.of(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES)); + if (mDefaultUnsupportedAdjustments != null) { + mAllowedAdjustments.removeAll(List.of(mDefaultUnsupportedAdjustments)); + } } } @@ -12063,104 +12091,41 @@ public class NotificationManagerService extends SystemService { } } - /** - * Returns whether the type adjustment is allowed for this particular package. - * If no package-specific restrictions have been set, defaults to the same value as - * isAdjustmentKeyTypeAllowed(type). - */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - protected boolean isTypeAdjustmentAllowedForPackage(String pkg, - @Adjustment.Types int type) { + protected @NonNull boolean isTypeAdjustmentAllowedForPackage(String pkg) { synchronized (mLock) { if (notificationClassificationUi()) { - if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { - Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); - if (enabled != null) { - return enabled.contains(type); - } - } - // If mClassificationTypePackagesEnabledTypes does not contain the pkg, or - // the stored set is null, return the default. - return isAdjustmentKeyTypeAllowed(type); + return !mClassificationTypeDeniedPackages.contains(pkg); } } - return false; - } - - @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - protected @NonNull Set<String> getPackagesWithKeyTypeAdjustmentSettings() { - if (notificationClassificationUi()) { - Set<String> packagesWithModifications = new ArraySet<String>(); - synchronized (mLock) { - for (String pkg : mClassificationTypePackagesEnabledTypes.keySet()) { - if (mClassificationTypePackagesEnabledTypes.get(pkg) != null) { - packagesWithModifications.add(pkg); - } - } - } - return packagesWithModifications; - } - return new ArraySet<String>(); + return true; } @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - protected @NonNull int[] getAllowedAdjustmentKeyTypesForPackage(String pkg) { + protected @NonNull String[] getTypeAdjustmentDeniedPackages() { synchronized (mLock) { if (notificationClassificationUi()) { - if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { - Set<Integer> enabled = mClassificationTypePackagesEnabledTypes.get(pkg); - if (enabled != null) { - // Convert Set to int[] for return. - int[] returnEnabled = new int[enabled.size()]; - int i = 0; - for (int val: enabled) { - returnEnabled[i] = val; - i++; - } - return returnEnabled; - } - } - // If package is not in the map, or the value is null, return the default. - return getAllowedAdjustmentKeyTypes(); + return mClassificationTypeDeniedPackages.toArray(new String[0]); } } - return new int[]{}; + return new String[]{}; } /** * Set whether a particular package can have its notification channels adjusted to have a * different type by NotificationAssistants. - * Note: once this method is called to enable or disable a specific type for a package, - * the global default is set as the starting point, and the type is enabled/disabled from - * there. Future changes to the global default will not apply automatically to this package. */ @FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void setAssistantAdjustmentKeyTypeStateForPackage(String pkg, - @Adjustment.Types int type, - boolean enabled) { + public void setTypeAdjustmentForPackageState(String pkg, boolean enabled) { if (!notificationClassificationUi()) { return; } synchronized (mLock) { - Set<Integer> enabledTypes = null; - if (mClassificationTypePackagesEnabledTypes.containsKey(pkg)) { - enabledTypes = mClassificationTypePackagesEnabledTypes.get(pkg); - } - if (enabledTypes == null) { - // Use global default to start. - enabledTypes = new ArraySet<Integer>(); - // Convert from int[] to Set<Integer> - for (int value : getAllowedAdjustmentKeyTypes()) { - enabledTypes.add(value); - } - } - if (enabled) { - enabledTypes.add(type); + mClassificationTypeDeniedPackages.remove(pkg); } else { - enabledTypes.remove(type); + mClassificationTypeDeniedPackages.add(pkg); } - mClassificationTypePackagesEnabledTypes.put(pkg, enabledTypes); } } @@ -12627,25 +12592,16 @@ public class NotificationManagerService extends SystemService { TextUtils.join(",", mAllowedAdjustmentKeyTypes)); out.endTag(null, ATT_ENABLED_TYPES); if (notificationClassificationUi()) { - out.startTag(null, TAG_TYPES_ENABLED_FOR_APPS); - for (String pkg: mClassificationTypePackagesEnabledTypes.keySet()) { - Set<Integer> allowedTypes = - mClassificationTypePackagesEnabledTypes.get(pkg); - if (allowedTypes != null) { - out.startTag(null, ATT_APP_ENABLED_TYPES); - out.attribute(null, ATT_PACKAGE, pkg); - out.attribute(null, ATT_TYPES, TextUtils.join(",", allowedTypes)); - out.endTag(null, ATT_APP_ENABLED_TYPES); - } - } - out.endTag(null, TAG_TYPES_ENABLED_FOR_APPS); + out.startTag(null, ATT_TYPES_DENIED_APPS); + out.attribute(null, ATT_TYPES, + TextUtils.join(",", mClassificationTypeDeniedPackages)); + out.endTag(null, ATT_TYPES_DENIED_APPS); } } } @Override - protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException, - XmlPullParserException { + protected void readExtraTag(String tag, TypedXmlPullParser parser) throws IOException { if (!notificationClassification()) { return; } @@ -12672,25 +12628,12 @@ public class NotificationManagerService extends SystemService { } } } - } else if (TAG_TYPES_ENABLED_FOR_APPS.equals(tag)) { - final int appsOuterDepth = parser.getDepth(); + } else if (notificationClassificationUi() && ATT_TYPES_DENIED_APPS.equals(tag)) { + final String apps = XmlUtils.readStringAttribute(parser, ATT_TYPES); synchronized (mLock) { - mClassificationTypePackagesEnabledTypes.clear(); - while (XmlUtils.nextElementWithin(parser, appsOuterDepth)) { - if (!ATT_APP_ENABLED_TYPES.equals(parser.getName())) { - continue; - } - final String app = XmlUtils.readStringAttribute(parser, ATT_PACKAGE); - Set<Integer> allowedTypes = new ArraySet<>(); - final String typesString = XmlUtils.readStringAttribute(parser, ATT_TYPES); - if (!TextUtils.isEmpty(typesString)) { - allowedTypes = Arrays.stream(typesString.split(",")) - .map(Integer::valueOf) - .collect(Collectors.toSet()); - } - // Empty type list is allowed, because empty type list signifies the user - // has manually cleared the package of allowed types. - mClassificationTypePackagesEnabledTypes.put(app, allowedTypes); + mClassificationTypeDeniedPackages.clear(); + if (!TextUtils.isEmpty(apps)) { + mClassificationTypeDeniedPackages.addAll(Arrays.asList(apps.split(","))); } } } diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java index 1aa5ac046ae9..7e853d9d2d0b 100644 --- a/services/core/java/com/android/server/notification/ZenLog.java +++ b/services/core/java/com/android/server/notification/ZenLog.java @@ -16,6 +16,7 @@ package com.android.server.notification; +import android.annotation.Nullable; import android.app.NotificationManager; import android.content.ComponentName; import android.media.AudioManager; @@ -26,6 +27,7 @@ import android.provider.Settings.Global; import android.service.notification.IConditionProvider; import android.service.notification.NotificationListenerService; import android.service.notification.ZenModeConfig; +import android.service.notification.ZenModeConfig.ConfigOrigin; import android.service.notification.ZenModeDiff; import android.util.LocalLog; @@ -119,16 +121,17 @@ public class ZenLog { append(TYPE_UNSUBSCRIBE, uri + "," + subscribeResult(provider, e)); } - public static void traceConfig(String reason, ComponentName triggeringComponent, - ZenModeConfig oldConfig, ZenModeConfig newConfig, int callingUid) { + public static void traceConfig(@ConfigOrigin int origin, String reason, + @Nullable ComponentName triggeringComponent, ZenModeConfig oldConfig, + ZenModeConfig newConfig, int callingUid) { ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(oldConfig, newConfig); - if (diff == null || !diff.hasDiff()) { - append(TYPE_CONFIG, reason + " no changes"); + if (!diff.hasDiff()) { + append(TYPE_CONFIG, reason + " (" + originToString(origin) + ") no changes"); } else { - append(TYPE_CONFIG, reason - + " - " + triggeringComponent + " : " + callingUid - + ",\n" + (newConfig != null ? newConfig.toString() : null) - + ",\n" + diff); + append(TYPE_CONFIG, reason + " (" + originToString(origin) + ") from uid " + callingUid + + (triggeringComponent != null ? " - " + triggeringComponent : "") + ",\n" + + (newConfig != null ? newConfig.toString() : null) + ",\n" + + diff); } } @@ -241,7 +244,22 @@ public class ZenLog { } } - private static String componentToString(ComponentName component) { + private static String originToString(@ConfigOrigin int origin) { + return switch (origin) { + case ZenModeConfig.ORIGIN_UNKNOWN -> "ORIGIN_UNKNOWN"; + case ZenModeConfig.ORIGIN_INIT -> "ORIGIN_INIT"; + case ZenModeConfig.ORIGIN_INIT_USER -> "ORIGIN_INIT_USER"; + case ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI -> "ORIGIN_USER_IN_SYSTEMUI"; + case ZenModeConfig.ORIGIN_APP -> "ORIGIN_APP"; + case ZenModeConfig.ORIGIN_SYSTEM -> "ORIGIN_SYSTEM"; + case ZenModeConfig.ORIGIN_RESTORE_BACKUP -> "ORIGIN_RESTORE_BACKUP"; + case ZenModeConfig.ORIGIN_USER_IN_APP -> "ORIGIN_USER_IN_APP"; + default -> origin + "??"; + }; + } + + @Nullable + private static String componentToString(@Nullable ComponentName component) { return component != null ? component.toShortString() : null; } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 0a63f3fb36d0..f089c3acdd70 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -659,7 +659,8 @@ public class ZenModeHelper { mContext.getString(R.string.zen_mode_implicit_deactivated), STATE_FALSE); setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule), - deactivated, ORIGIN_APP, callingUid); + deactivated, ORIGIN_APP, + "applyGlobalZenModeAsImplicitZenRule: " + callingPkg, callingUid); } } else { // Either create a new rule with a default ZenPolicy, or update an existing rule's @@ -971,26 +972,27 @@ public class ZenModeHelper { if (Flags.modesApi()) { if (rule != null && canManageAutomaticZenRule(rule, callingUid)) { setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule), - condition, origin, callingUid); + condition, origin, "setAzrState: " + rule.id, callingUid); } } else { ArrayList<ZenRule> rules = new ArrayList<>(); rules.add(rule); // rule may be null and throw NPE in the next method. - setAutomaticZenRuleStateLocked(newConfig, rules, condition, origin, callingUid); + setAutomaticZenRuleStateLocked(newConfig, rules, condition, origin, + "setAzrState: " + (rule != null ? rule.id : "null!"), callingUid); } } } - void setAutomaticZenRuleStateFromConditionProvider(UserHandle user, Uri ruleDefinition, + void setAutomaticZenRuleStateFromConditionProvider(UserHandle user, Uri ruleConditionId, Condition condition, @ConfigOrigin int origin, int callingUid) { - checkSetRuleStateOrigin("setAutomaticZenRuleState(Uri ruleDefinition)", origin); + checkSetRuleStateOrigin("setAutomaticZenRuleStateFromConditionProvider", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { ZenModeConfig config = getConfigLocked(user); if (config == null) return; newConfig = config.copy(); - List<ZenRule> matchingRules = findMatchingRules(newConfig, ruleDefinition, condition); + List<ZenRule> matchingRules = findMatchingRules(newConfig, ruleConditionId, condition); if (Flags.modesApi()) { for (int i = matchingRules.size() - 1; i >= 0; i--) { if (!canManageAutomaticZenRule(matchingRules.get(i), callingUid)) { @@ -998,13 +1000,14 @@ public class ZenModeHelper { } } } - setAutomaticZenRuleStateLocked(newConfig, matchingRules, condition, origin, callingUid); + setAutomaticZenRuleStateLocked(newConfig, matchingRules, condition, origin, + "setAzrStateFromCps: " + ruleConditionId, callingUid); } } @GuardedBy("mConfigLock") private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List<ZenRule> rules, - Condition condition, @ConfigOrigin int origin, int callingUid) { + Condition condition, @ConfigOrigin int origin, String reason, int callingUid) { if (rules == null || rules.isEmpty()) return; if (!Flags.modesUi()) { @@ -1015,7 +1018,7 @@ public class ZenModeHelper { for (ZenRule rule : rules) { applyConditionAndReconsiderOverride(rule, condition, origin); - setConfigLocked(config, rule.component, origin, "conditionChanged", callingUid); + setConfigLocked(config, rule.component, origin, reason, callingUid); } } @@ -2111,13 +2114,14 @@ public class ZenModeHelper { } @GuardedBy("mConfigLock") - private boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent, - @ConfigOrigin int origin, String reason, int callingUid) { + private boolean setConfigLocked(ZenModeConfig config, + @Nullable ComponentName triggeringComponent, @ConfigOrigin int origin, String reason, + int callingUid) { return setConfigLocked(config, origin, reason, triggeringComponent, true /*setRingerMode*/, callingUid); } - void setConfig(ZenModeConfig config, ComponentName triggeringComponent, + void setConfig(ZenModeConfig config, @Nullable ComponentName triggeringComponent, @ConfigOrigin int origin, String reason, int callingUid) { synchronized (mConfigLock) { setConfigLocked(config, triggeringComponent, origin, reason, callingUid); @@ -2126,7 +2130,7 @@ public class ZenModeHelper { @GuardedBy("mConfigLock") private boolean setConfigLocked(ZenModeConfig config, @ConfigOrigin int origin, - String reason, ComponentName triggeringComponent, boolean setRingerMode, + String reason, @Nullable ComponentName triggeringComponent, boolean setRingerMode, int callingUid) { final long identity = Binder.clearCallingIdentity(); try { @@ -2149,7 +2153,7 @@ public class ZenModeHelper { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable()); - ZenLog.traceConfig(reason, triggeringComponent, mConfig, config, callingUid); + ZenLog.traceConfig(origin, reason, triggeringComponent, mConfig, config, callingUid); // send some broadcasts Policy newPolicy = getNotificationPolicy(config); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f60e086e7c5d..61429a41370c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4255,8 +4255,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService CarrierAppUtils.disableCarrierAppsUntilPrivileged( mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext); - disableSkuSpecificApps(); - // Read the compatibilty setting when the system is ready. boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), @@ -4390,29 +4388,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } - //TODO: b/111402650 - private void disableSkuSpecificApps() { - String[] apkList = mContext.getResources().getStringArray( - R.array.config_disableApksUnlessMatchedSku_apk_list); - String[] skuArray = mContext.getResources().getStringArray( - R.array.config_disableApkUnlessMatchedSku_skus_list); - if (ArrayUtils.isEmpty(apkList)) { - return; - } - String sku = SystemProperties.get("ro.boot.hardware.sku"); - if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) { - return; - } - final Computer snapshot = snapshotComputer(); - for (String packageName : apkList) { - setSystemAppHiddenUntilInstalled(snapshot, packageName, true); - final List<UserInfo> users = mInjector.getUserManagerInternal().getUsers(false); - for (int i = 0; i < users.size(); i++) { - setSystemAppInstallState(snapshot, packageName, false, users.get(i).id); - } - } - } - public PackageFreezer freezePackage(String packageName, int userId, String killReason, int exitInfoReason, InstallRequest request) { return freezePackage(packageName, userId, killReason, exitInfoReason, request, diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index f4d4c5be035e..b85e6894b910 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -33,6 +33,7 @@ import static android.os.UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY; import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN; import static android.os.UserManager.USER_OPERATION_ERROR_USER_RESTRICTED; import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE; +import static android.os.UserManager.supportsMultipleUsers; import static android.provider.Settings.Secure.HIDE_PRIVATESPACE_ENTRY_POINT; import static com.android.internal.app.SetScreenLockDialogActivity.EXTRA_ORIGIN_USER_ID; @@ -1156,7 +1157,7 @@ public class UserManagerService extends IUserManager.Stub { showHsumNotificationIfNeeded(); - if (Flags.addUiForSoundsFromBackgroundUsers()) { + if (shouldShowNotificationForBackgroundUserSounds()) { new BackgroundUserSoundNotifier(mContext); } } @@ -8486,6 +8487,17 @@ public class UserManagerService extends IUserManager.Stub { } /** + * @hide + * Checks whether to show a notification for sounds (e.g., alarms, timers, etc.) from + * background users. + */ + public static boolean shouldShowNotificationForBackgroundUserSounds() { + return Flags.addUiForSoundsFromBackgroundUsers() && Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_showNotificationForBackgroundUserAlarms) + && supportsMultipleUsers(); + } + + /** * Returns instance of {@link com.android.server.pm.UserJourneyLogger}. */ public UserJourneyLogger getUserJourneyLogger() { diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index deaa8d8feae1..44d787f790cf 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -356,7 +356,7 @@ public final class PermissionPolicyService extends SystemService { try { manager = new PermissionControllerManager( getUserContext(getContext(), user), PermissionThread.getHandler()); - } catch (IllegalArgumentException exception) { + } catch (IllegalStateException exception) { // There's a possible race condition when a user is being removed Log.e(LOG_TAG, "Could not create PermissionControllerManager for user" + user, exception); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index f9e4022f04a0..090707db50a5 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -30,6 +30,7 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; import static android.os.PowerManagerInternal.isInteractive; import static android.os.PowerManagerInternal.wakefulnessToString; +import static android.service.dreams.Flags.allowDreamWhenPostured; import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN; import static com.android.server.deviceidle.Flags.disableWakelocksInLightIdle; @@ -216,6 +217,8 @@ public final class PowerManagerService extends SystemService private static final int DIRTY_ATTENTIVE = 1 << 14; // Dirty bit: display group wakefulness has changed private static final int DIRTY_DISPLAY_GROUP_WAKEFULNESS = 1 << 16; + // Dirty bit: device postured state has changed + private static final int DIRTY_POSTURED_STATE = 1 << 17; // Summarizes the state of all active wakelocks. static final int WAKE_LOCK_CPU = 1 << 0; @@ -500,6 +503,11 @@ public final class PowerManagerService extends SystemService // The current dock state. private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + /** + * Whether the device is upright and stationary. + */ + private boolean mDevicePostured; + // True to decouple auto-suspend mode from the display state. private boolean mDecoupleHalAutoSuspendModeFromDisplayConfig; @@ -530,6 +538,9 @@ public final class PowerManagerService extends SystemService // Default value for dreams activate-on-dock private boolean mDreamsActivatedOnDockByDefaultConfig; + /** Default value for whether dreams are activated when postured (stationary + upright) */ + private boolean mDreamsActivatedWhilePosturedByDefaultConfig; + // True if dreams can run while not plugged in. private boolean mDreamsEnabledOnBatteryConfig; @@ -558,6 +569,9 @@ public final class PowerManagerService extends SystemService // True if dreams should be activated on dock. private boolean mDreamsActivateOnDockSetting; + /** Whether dreams should be activated when device is postured (stationary and upright) */ + private boolean mDreamsActivateWhilePosturedSetting; + // True if doze should not be started until after the screen off transition. private boolean mDozeAfterScreenOff; @@ -1471,6 +1485,9 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK), false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED), + false, mSettingsObserver, UserHandle.USER_ALL); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, mSettingsObserver, UserHandle.USER_ALL); @@ -1549,6 +1566,8 @@ public final class PowerManagerService extends SystemService com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); mDreamsActivatedOnDockByDefaultConfig = resources.getBoolean( com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); + mDreamsActivatedWhilePosturedByDefaultConfig = resources.getBoolean( + com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault); mDreamsEnabledOnBatteryConfig = resources.getBoolean( com.android.internal.R.bool.config_dreamsEnabledOnBattery); mDreamsBatteryLevelMinimumWhenPoweredConfig = resources.getInteger( @@ -1589,6 +1608,10 @@ public final class PowerManagerService extends SystemService Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, mDreamsActivatedOnDockByDefaultConfig ? 1 : 0, UserHandle.USER_CURRENT) != 0); + mDreamsActivateWhilePosturedSetting = (Settings.Secure.getIntForUser(resolver, + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, + mDreamsActivatedWhilePosturedByDefaultConfig ? 1 : 0, + UserHandle.USER_CURRENT) != 0); mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT, UserHandle.USER_CURRENT); @@ -3336,7 +3359,7 @@ public final class PowerManagerService extends SystemService if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS - | DIRTY_SCREEN_BRIGHTNESS_BOOST)) == 0) { + | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_POSTURED_STATE)) == 0) { return changed; } final long time = mClock.uptimeMillis(); @@ -3375,7 +3398,8 @@ public final class PowerManagerService extends SystemService private boolean shouldNapAtBedTimeLocked() { return mDreamsActivateOnSleepSetting || (mDreamsActivateOnDockSetting - && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED); + && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) + || (mDreamsActivateWhilePosturedSetting && mDevicePostured); } /** @@ -4489,6 +4513,17 @@ public final class PowerManagerService extends SystemService } } + private void setDevicePosturedInternal(boolean isPostured) { + if (!allowDreamWhenPostured()) { + return; + } + synchronized (mLock) { + mDevicePostured = isPostured; + mDirty |= DIRTY_POSTURED_STATE; + updatePowerStateLocked(); + } + } + private void setUserActivityTimeoutOverrideFromWindowManagerInternal(long timeoutMillis) { synchronized (mLock) { if (mUserActivityTimeoutOverrideFromWindowManager != timeoutMillis) { @@ -4794,6 +4829,8 @@ public final class PowerManagerService extends SystemService + mDreamsActivatedOnSleepByDefaultConfig); pw.println(" mDreamsActivatedOnDockByDefaultConfig=" + mDreamsActivatedOnDockByDefaultConfig); + pw.println(" mDreamsActivatedWhilePosturedByDefaultConfig=" + + mDreamsActivatedWhilePosturedByDefaultConfig); pw.println(" mDreamsEnabledOnBatteryConfig=" + mDreamsEnabledOnBatteryConfig); pw.println(" mDreamsBatteryLevelMinimumWhenPoweredConfig=" @@ -4805,6 +4842,8 @@ public final class PowerManagerService extends SystemService pw.println(" mDreamsEnabledSetting=" + mDreamsEnabledSetting); pw.println(" mDreamsActivateOnSleepSetting=" + mDreamsActivateOnSleepSetting); pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting); + pw.println(" mDreamsActivateWhilePosturedSetting=" + + mDreamsActivateWhilePosturedSetting); pw.println(" mDozeAfterScreenOff=" + mDozeAfterScreenOff); pw.println(" mBrightWhenDozingConfig=" + mBrightWhenDozingConfig); pw.println(" mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig); @@ -7388,6 +7427,11 @@ public final class PowerManagerService extends SystemService public boolean isAmbientDisplaySuppressed() { return mAmbientDisplaySuppressionController.isSuppressed(); } + + @Override + public void setDevicePostured(boolean isPostured) { + setDevicePosturedInternal(isPostured); + } } /** diff --git a/services/core/java/com/android/server/power/hint/TEST_MAPPING b/services/core/java/com/android/server/power/hint/TEST_MAPPING index 545070050977..fd81277e9ba4 100644 --- a/services/core/java/com/android/server/power/hint/TEST_MAPPING +++ b/services/core/java/com/android/server/power/hint/TEST_MAPPING @@ -15,5 +15,22 @@ {"exclude-annotation": "org.junit.Ignore"} ] } + ], + "postsubmit": [ + { + "name": "CtsSystemHealthTestCases", + "options": [ + {"exclude-annotation": "androidx.test.filters.FlakyTest"}, + {"exclude-annotation": "org.junit.Ignore"} + ] + }, + { + "name": "CtsOsTestCases", + "options": [ + {"include-filter": "android.os.health.cts.HeadroomTest"}, + {"exclude-annotation": "androidx.test.filters.FlakyTest"}, + {"exclude-annotation": "org.junit.Ignore"} + ] + } ] }
\ No newline at end of file diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java index 9206cce12cd6..68768b8fa223 100644 --- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java +++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java @@ -225,11 +225,19 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting public static final int WAKE_LOCK_WEIGHT = 50; + /** + * Minimum duration of a battery session. Attempt to automatically start a new + * session within this interval are ignored. Explicit resets (e.g. with an adb command) are + * not affected by this restriction. + */ + private static final long MIN_BATTERY_SESSION_DURATION_MILLIS = 60000; + public static final int RESET_REASON_CORRUPT_FILE = 1; public static final int RESET_REASON_ADB_COMMAND = 2; public static final int RESET_REASON_FULL_CHARGE = 3; public static final int RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE = 4; public static final int RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION = 5; + @NonNull private final MonotonicClock mMonotonicClock; @@ -305,6 +313,81 @@ public class BatteryStatsImpl extends BatteryStats { private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray(); private boolean mMoveWscLoggingToNotifierEnabled = false; + static class BatteryStatsSession { + private final BatteryStatsHistory mHistory; + private final long mMonotonicStartTime; + private final long mStartClockTime; + private final long mEstimatedBatteryCapacityMah; + private final long mBatteryTimeRemainingMs; + private final long mChargeTimeRemainingMs; + private final String[] mCustomEnergyConsumerNames; + private final BatteryStatsImpl mBatteryStats; + + BatteryStatsSession(BatteryStatsHistory history, long monotonicStartTime, + long startClockTime, long batteryTimeRemainingMs, long chargeTimeRemainingMs, + long estimatedBatteryCapacityMah, String[] customEnergyConsumerNames, + BatteryStatsImpl batteryStats) { + mHistory = history; + mMonotonicStartTime = monotonicStartTime; + mStartClockTime = startClockTime; + mEstimatedBatteryCapacityMah = estimatedBatteryCapacityMah; + mBatteryTimeRemainingMs = batteryTimeRemainingMs; + mChargeTimeRemainingMs = chargeTimeRemainingMs; + mCustomEnergyConsumerNames = customEnergyConsumerNames; + mBatteryStats = batteryStats; + } + + BatteryStatsHistory getHistory() { + return mHistory; + } + + long getMonotonicStartTime() { + return mMonotonicStartTime; + } + + long getStartClockTime() { + return mStartClockTime; + } + + long getBatteryTimeRemainingMs() { + return mBatteryTimeRemainingMs; + } + + long getChargeTimeRemainingMs() { + return mChargeTimeRemainingMs; + } + + double getEstimatedBatteryCapacity() { + return mEstimatedBatteryCapacityMah; + } + + String[] getCustomEnergyConsumerNames() { + return mCustomEnergyConsumerNames; + } + + /** @deprecated This method will be removed once PowerCalculators are removed from the + * code base. */ + @Deprecated + public BatteryStatsImpl getBatteryStats() { + return mBatteryStats; + } + } + + BatteryStatsSession getBatteryStatsSession() { + synchronized (this) { + long elapsedTimeUs = mClock.elapsedRealtime() * 1000; + long batteryTimeRemainingUs = computeBatteryTimeRemaining(elapsedTimeUs); + long batteryTimeRemainingMs = + batteryTimeRemainingUs >= 0 ? batteryTimeRemainingUs / 1000 : -1; + long chargeTimeRemainingUs = computeChargeTimeRemaining(elapsedTimeUs); + long chargeTimeRemainingMs = + chargeTimeRemainingUs >= 0 ? chargeTimeRemainingUs / 1000 : -1; + return new BatteryStatsSession(mHistory, getMonotonicStartTime(), getStartClockTime(), + batteryTimeRemainingMs, chargeTimeRemainingMs, getEstimatedBatteryCapacity(), + getCustomEnergyConsumerNames(), this); + } + } + private ScreenPowerStatsCollector.ScreenUsageTimeRetriever mScreenUsageTimeRetriever = new ScreenPowerStatsCollector.ScreenUsageTimeRetriever() { @@ -554,6 +637,7 @@ public class BatteryStatsImpl extends BatteryStats { } private boolean mSaveBatteryUsageStatsOnReset; + private boolean mResetBatteryHistoryOnNewSession; private boolean mAccumulateBatteryUsageStats; private BatteryUsageStatsProvider mBatteryUsageStatsProvider; private PowerStatsStore mPowerStatsStore; @@ -1753,8 +1837,7 @@ public class BatteryStatsImpl extends BatteryStats { */ private LongSamplingCounterArray mBinderThreadCpuTimesUs; - @VisibleForTesting - protected PowerProfile mPowerProfile; + private final PowerProfile mPowerProfile; @VisibleForTesting @GuardedBy("this") @@ -11627,10 +11710,6 @@ public class BatteryStatsImpl extends BatteryStats { setDisplayCountLocked(mPowerProfile.getNumDisplays()); } - PowerProfile getPowerProfile() { - return mPowerProfile; - } - /** * Starts tracking CPU time-in-state for threads of the system server process, * keeping a separate account of threads receiving incoming binder calls. @@ -12074,6 +12153,13 @@ public class BatteryStatsImpl extends BatteryStats { mAccumulateBatteryUsageStats = accumulateBatteryUsageStats; } + /** + * Enables or disables battery history reset at the beginning of a battery stats session. + */ + public void resetBatteryHistoryOnNewSession(boolean enabled) { + mResetBatteryHistoryOnNewSession = enabled; + } + @GuardedBy("this") public void resetAllStatsAndHistoryLocked(int reason) { final long mSecUptime = mClock.uptimeMillis(); @@ -12107,11 +12193,29 @@ public class BatteryStatsImpl extends BatteryStats { initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); } + /** + * Starts a new battery stats session, resetting counters and timers. If this method is called + * before MIN_BATTERY_SESSION_DURATION_MILLIS from the beginning of the current session, the + * call is ignored. + */ + public void startNewSession(int reason) { + if (mMonotonicClock.monotonicTime() + < mMonotonicStartTime + MIN_BATTERY_SESSION_DURATION_MILLIS) { + Slog.i(TAG, "Battery session session duration is too short, ignoring reset request"); + return; + } + + mHandler.post(()-> { + saveBatteryUsageStatsOnReset(); + synchronized (BatteryStatsImpl.this) { + resetAllStatsLocked(mClock.uptimeMillis(), mClock.elapsedRealtime(), reason); + } + }); + } + @GuardedBy("this") private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, int resetReason) { - saveBatteryUsageStatsOnReset(resetReason); - final long uptimeUs = uptimeMillis * 1000; final long elapsedRealtimeUs = elapsedRealtimeMillis * 1000; mStartCount = 0; @@ -12250,7 +12354,11 @@ public class BatteryStatsImpl extends BatteryStats { initDischarge(elapsedRealtimeUs); - mHistory.reset(); + if ((resetReason != RESET_REASON_FULL_CHARGE + && resetReason != RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION) + || mResetBatteryHistoryOnNewSession) { + mHistory.reset(); + } // Store the empty state to disk to ensure consistency writeSyncLocked(); @@ -12266,14 +12374,14 @@ public class BatteryStatsImpl extends BatteryStats { mHandler.sendEmptyMessage(MSG_REPORT_RESET_STATS); } - private void saveBatteryUsageStatsOnReset(int resetReason) { - if (!mSaveBatteryUsageStatsOnReset - || resetReason == BatteryStatsImpl.RESET_REASON_CORRUPT_FILE) { + private void saveBatteryUsageStatsOnReset() { + if (!mSaveBatteryUsageStatsOnReset) { return; } if (mAccumulateBatteryUsageStats) { - mBatteryUsageStatsProvider.accumulateBatteryUsageStats(this); + mBatteryUsageStatsProvider.accumulateBatteryUsageStats(getBatteryStatsSession(), + mHandler); } else { final BatteryUsageStats batteryUsageStats; synchronized (this) { @@ -14926,7 +15034,7 @@ public class BatteryStatsImpl extends BatteryStats { "Resetting due to long plug in duration. elapsed time = " + elapsedRealtimeMs + " ms, last plug in time = " + mBatteryPluggedInRealTimeMs + " ms, last reset time = " + mRealtimeStartUs / 1000); - resetAllStatsAndHistoryLocked(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); + startNewSession(RESET_REASON_PLUGGED_IN_FOR_LONG_DURATION); } scheduleNextResetWhilePluggedInCheck(); @@ -15064,7 +15172,7 @@ public class BatteryStatsImpl extends BatteryStats { }); } doWrite = true; - resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); + startNewSession(RESET_REASON_FULL_CHARGE); if (chargeUah > 0 && level > 0) { // Only use the reported coulomb charge value if it is supported and reported. mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); @@ -15980,6 +16088,8 @@ public class BatteryStatsImpl extends BatteryStats { if (mEnergyConsumerStatsConfig != null && !mEnergyConsumerStatsConfig.isCompatible(config)) { // Supported power buckets changed since last boot. + // Save accumulated battery usage stats before resetting + saveBatteryUsageStatsOnReset(); // Existing data is no longer reliable. resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); @@ -15999,7 +16109,10 @@ public class BatteryStatsImpl extends BatteryStats { } } else { if (mEnergyConsumerStatsConfig != null) { - // EnergyConsumer no longer supported, wipe out the existing data. + // EnergyConsumer no longer supported + // Save accumulated battery usage stats before resetting + saveBatteryUsageStatsOnReset(); + // Wipe out the current battery session data. resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), RESET_REASON_ENERGY_CONSUMER_BUCKETS_CHANGE); } diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java index 8c588b4c9b98..977c6db66106 100644 --- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java +++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java @@ -17,6 +17,7 @@ package com.android.server.power.stats; import android.annotation.NonNull; +import android.annotation.UserIdInt; import android.content.Context; import android.hardware.SensorManager; import android.os.BatteryConsumer; @@ -25,6 +26,8 @@ import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.Handler; import android.os.Process; +import android.os.UidBatteryConsumer; +import android.os.UserHandle; import android.util.Log; import android.util.LogWriter; import android.util.Slog; @@ -34,6 +37,8 @@ import com.android.internal.os.Clock; import com.android.internal.os.CpuScalingPolicies; import com.android.internal.os.MonotonicClock; import com.android.internal.os.PowerProfile; +import com.android.internal.util.ArrayUtils; +import com.android.server.power.stats.BatteryStatsImpl.BatteryStatsSession; import java.io.PrintWriter; import java.util.ArrayList; @@ -58,7 +63,6 @@ public class BatteryUsageStatsProvider { private final MonotonicClock mMonotonicClock; private final Object mLock = new Object(); private List<PowerCalculator> mPowerCalculators; - private UserPowerCalculator mUserPowerCalculator; private long mLastAccumulationMonotonicHistorySize; private static class AccumulatedBatteryUsageStats { @@ -81,7 +85,6 @@ public class BatteryUsageStatsProvider { mAccumulatedBatteryUsageStatsSpanSize = accumulatedBatteryUsageStatsSpanSize; mClock = clock; mMonotonicClock = monotonicClock; - mUserPowerCalculator = new UserPowerCalculator(); mPowerStatsStore.addSectionReader(new BatteryUsageStatsSection.Reader()); mPowerStatsStore.addSectionReader(new AccumulatedBatteryUsageStatsSection.Reader()); @@ -195,22 +198,20 @@ public class BatteryUsageStatsProvider { mLastAccumulationMonotonicHistorySize = historySize; } + BatteryStatsSession session = stats.getBatteryStatsSession(); + // No need to store the accumulated stats asynchronously, as the entire accumulation // operation is async - handler.post(() -> accumulateBatteryUsageStats(stats, false)); + handler.post(() -> accumulateBatteryUsageStats(session, handler)); } /** * Computes BatteryUsageStats for the period since the last accumulated stats were stored, - * adds them to the accumulated stats and asynchronously saves the result. + * adds them to the accumulated stats and saves the result on the handler thread. */ - public void accumulateBatteryUsageStats(BatteryStatsImpl stats) { - accumulateBatteryUsageStats(stats, true); - } - - private void accumulateBatteryUsageStats(BatteryStatsImpl stats, boolean storeAsync) { + public void accumulateBatteryUsageStats(BatteryStatsSession session, Handler handler) { AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats(); - updateAccumulatedBatteryUsageStats(accumulatedStats, stats); + updateAccumulatedBatteryUsageStats(accumulatedStats, session); PowerStatsSpan powerStatsSpan = new PowerStatsSpan(AccumulatedBatteryUsageStatsSection.ID); powerStatsSpan.addSection( @@ -219,12 +220,12 @@ public class BatteryUsageStatsProvider { accumulatedStats.startWallClockTime, accumulatedStats.endMonotonicTime - accumulatedStats.startMonotonicTime); mMonotonicClock.write(); - if (storeAsync) { - mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan, - accumulatedStats.builder::discard); - } else { + if (handler.getLooper().isCurrentThread()) { mPowerStatsStore.storePowerStatsSpan(powerStatsSpan); accumulatedStats.builder.discard(); + } else { + mPowerStatsStore.storePowerStatsSpanAsync(powerStatsSpan, + accumulatedStats.builder::discard); } } @@ -252,9 +253,10 @@ public class BatteryUsageStatsProvider { synchronized (stats) { stats.prepareForDumpLocked(); } + BatteryStatsSession session = stats.getBatteryStatsSession(); final long currentTimeMillis = mClock.currentTimeMillis(); for (int i = 0; i < queries.size(); i++) { - results.add(getBatteryUsageStats(stats, queries.get(i), currentTimeMillis)); + results.add(getBatteryUsageStats(session, queries.get(i), currentTimeMillis)); } return results; @@ -265,22 +267,23 @@ public class BatteryUsageStatsProvider { */ public BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats, BatteryUsageStatsQuery query) { - return getBatteryUsageStats(stats, query, mClock.currentTimeMillis()); + return getBatteryUsageStats(stats.getBatteryStatsSession(), query, + mClock.currentTimeMillis()); } - private BatteryUsageStats getBatteryUsageStats(BatteryStatsImpl stats, + private BatteryUsageStats getBatteryUsageStats(BatteryStatsSession session, BatteryUsageStatsQuery query, long currentTimeMs) { BatteryUsageStats batteryUsageStats; if ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_ACCUMULATED) != 0) { - batteryUsageStats = getAccumulatedBatteryUsageStats(stats, query); + batteryUsageStats = getAccumulatedBatteryUsageStats(session, query); } else if (query.getAggregatedToTimestamp() == 0) { - BatteryUsageStats.Builder builder = computeBatteryUsageStats(stats, query, + BatteryUsageStats.Builder builder = computeBatteryUsageStats(session, query, query.getMonotonicStartTime(), query.getMonotonicEndTime(), currentTimeMs); batteryUsageStats = builder.build(); } else { - batteryUsageStats = getAggregatedBatteryUsageStats(stats, query); + batteryUsageStats = getAggregatedBatteryUsageStats(session, query); } if (DEBUG) { Slog.d(TAG, "query = " + query); @@ -291,13 +294,13 @@ public class BatteryUsageStatsProvider { return batteryUsageStats; } - private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsImpl stats, + private BatteryUsageStats getAccumulatedBatteryUsageStats(BatteryStatsSession session, BatteryUsageStatsQuery query) { AccumulatedBatteryUsageStats accumulatedStats = loadAccumulatedBatteryUsageStats(); if (accumulatedStats.endMonotonicTime == MonotonicClock.UNDEFINED || mMonotonicClock.monotonicTime() - accumulatedStats.endMonotonicTime > query.getMaxStatsAge()) { - updateAccumulatedBatteryUsageStats(accumulatedStats, stats); + updateAccumulatedBatteryUsageStats(accumulatedStats, session); } return accumulatedStats.builder.build(); } @@ -329,19 +332,19 @@ public class BatteryUsageStatsProvider { } private void updateAccumulatedBatteryUsageStats(AccumulatedBatteryUsageStats accumulatedStats, - BatteryStatsImpl stats) { + BatteryStatsSession session) { long startMonotonicTime = accumulatedStats.endMonotonicTime; if (startMonotonicTime == MonotonicClock.UNDEFINED) { - startMonotonicTime = stats.getMonotonicStartTime(); + startMonotonicTime = session.getMonotonicStartTime(); } long endWallClockTime = mClock.currentTimeMillis(); long endMonotonicTime = mMonotonicClock.monotonicTime(); if (accumulatedStats.builder == null) { accumulatedStats.builder = new BatteryUsageStats.Builder( - stats.getCustomEnergyConsumerNames(), true, true, true, 0); - accumulatedStats.startWallClockTime = stats.getStartClockTime(); - accumulatedStats.startMonotonicTime = stats.getMonotonicStartTime(); + session.getCustomEnergyConsumerNames(), true, true, true, 0); + accumulatedStats.startWallClockTime = session.getStartClockTime(); + accumulatedStats.startMonotonicTime = session.getMonotonicStartTime(); accumulatedStats.builder.setStatsStartTimestamp(accumulatedStats.startWallClockTime); } @@ -350,121 +353,118 @@ public class BatteryUsageStatsProvider { accumulatedStats.builder.setStatsEndTimestamp(endWallClockTime); accumulatedStats.builder.setStatsDuration(endWallClockTime - startMonotonicTime); - mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, stats.getHistory(), + mPowerAttributor.estimatePowerConsumption(accumulatedStats.builder, session.getHistory(), startMonotonicTime, endMonotonicTime); - populateGeneralInfo(accumulatedStats.builder, stats); + populateBatterySessionInfo(accumulatedStats.builder, session); } - private BatteryUsageStats.Builder computeBatteryUsageStats(BatteryStatsImpl stats, + private BatteryUsageStats.Builder computeBatteryUsageStats(BatteryStatsSession session, BatteryUsageStatsQuery query, long monotonicStartTime, long monotonicEndTime, long currentTimeMs) { final boolean includeProcessStateData = ((query.getFlags() - & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0) - && stats.isProcessStateDataAvailable(); + & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0); final boolean includeVirtualUids = ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0); final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold(); - String[] customEnergyConsumerNames; - synchronized (stats) { - customEnergyConsumerNames = stats.getCustomEnergyConsumerNames(); - } + String[] customEnergyConsumerNames = session.getCustomEnergyConsumerNames(); final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder( customEnergyConsumerNames, includeProcessStateData, query.isScreenStateDataNeeded(), query.isPowerStateDataNeeded(), minConsumedPowerThreshold); - synchronized (stats) { - final List<PowerCalculator> powerCalculators = getPowerCalculators(); - boolean usePowerCalculators = !powerCalculators.isEmpty(); - if (usePowerCalculators - && (monotonicStartTime != MonotonicClock.UNDEFINED - || monotonicEndTime != MonotonicClock.UNDEFINED)) { - Slog.wtfStack(TAG, "BatteryUsageStatsQuery specifies a time " - + "range that is incompatible with PowerCalculators: " - + powerCalculators); - usePowerCalculators = false; - } - - if (monotonicStartTime == MonotonicClock.UNDEFINED) { - monotonicStartTime = stats.getMonotonicStartTime(); - } - batteryUsageStatsBuilder.setStatsStartTimestamp(stats.getStartClockTime() - + (monotonicStartTime - stats.getMonotonicStartTime())); - if (monotonicEndTime != MonotonicClock.UNDEFINED) { - batteryUsageStatsBuilder.setStatsEndTimestamp(stats.getStartClockTime() - + (monotonicEndTime - stats.getMonotonicStartTime())); - } else { - batteryUsageStatsBuilder.setStatsEndTimestamp(currentTimeMs); - } + final List<PowerCalculator> powerCalculators = getPowerCalculators(); + boolean usePowerCalculators = !powerCalculators.isEmpty(); + if (usePowerCalculators + && (monotonicStartTime != MonotonicClock.UNDEFINED + || monotonicEndTime != MonotonicClock.UNDEFINED)) { + Slog.wtfStack(TAG, "BatteryUsageStatsQuery specifies a time " + + "range that is incompatible with PowerCalculators: " + + powerCalculators); + usePowerCalculators = false; + } - if (usePowerCalculators) { - final long realtimeUs = mClock.elapsedRealtime() * 1000; - final long uptimeUs = mClock.uptimeMillis() * 1000; - final int[] powerComponents = query.getPowerComponents(); - SparseArray<? extends BatteryStats.Uid> uidStats = stats.getUidStats(); - for (int i = uidStats.size() - 1; i >= 0; i--) { - final BatteryStats.Uid uid = uidStats.valueAt(i); - if (!includeVirtualUids && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) { - continue; - } + if (monotonicStartTime == MonotonicClock.UNDEFINED) { + monotonicStartTime = session.getMonotonicStartTime(); + } + batteryUsageStatsBuilder.setStatsStartTimestamp(session.getStartClockTime() + + (monotonicStartTime - session.getMonotonicStartTime())); + if (monotonicEndTime != MonotonicClock.UNDEFINED) { + batteryUsageStatsBuilder.setStatsEndTimestamp(session.getStartClockTime() + + (monotonicEndTime - session.getMonotonicStartTime())); + } else { + batteryUsageStatsBuilder.setStatsEndTimestamp(currentTimeMs); + } - batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid); - } - for (int i = 0, count = powerCalculators.size(); i < count; i++) { - PowerCalculator powerCalculator = powerCalculators.get(i); - if (powerComponents != null) { - boolean include = false; - for (int powerComponent : powerComponents) { - if (powerCalculator.isPowerComponentSupported(powerComponent)) { - include = true; - break; - } - } - if (!include) { - continue; - } - } - powerCalculator.calculate(batteryUsageStatsBuilder, stats, realtimeUs, uptimeUs, - query); - } - } - if ((query.getFlags() - & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) { - batteryUsageStatsBuilder.setBatteryHistory(stats.copyHistory()); - } + if (usePowerCalculators) { + BatteryStatsImpl stats = session.getBatteryStats(); + applyPowerCalculators(batteryUsageStatsBuilder, stats, query, includeVirtualUids); + } + if ((query.getFlags() + & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_HISTORY) != 0) { + batteryUsageStatsBuilder.setBatteryHistory(session.getHistory().copy()); } - mPowerAttributor.estimatePowerConsumption(batteryUsageStatsBuilder, stats.getHistory(), + mPowerAttributor.estimatePowerConsumption(batteryUsageStatsBuilder, session.getHistory(), monotonicStartTime, monotonicEndTime); // Combine apps by the user if necessary - mUserPowerCalculator.calculate(batteryUsageStatsBuilder, stats, 0, 0, query); + buildUserBatteryConsumers(batteryUsageStatsBuilder, query.getUserIds()); - populateGeneralInfo(batteryUsageStatsBuilder, stats); + populateBatterySessionInfo(batteryUsageStatsBuilder, session); return batteryUsageStatsBuilder; } - private void populateGeneralInfo(BatteryUsageStats.Builder builder, BatteryStatsImpl stats) { - builder.setBatteryCapacity(stats.getEstimatedBatteryCapacity()); - final long batteryTimeRemainingMs = stats.computeBatteryTimeRemaining( - mClock.elapsedRealtime() * 1000); - if (batteryTimeRemainingMs != -1) { - builder.setBatteryTimeRemainingMs(batteryTimeRemainingMs / 1000); - } - final long chargeTimeRemainingMs = stats.computeChargeTimeRemaining( - mClock.elapsedRealtime() * 1000); - if (chargeTimeRemainingMs != -1) { - builder.setChargeTimeRemainingMs(chargeTimeRemainingMs / 1000); + private void applyPowerCalculators(BatteryUsageStats.Builder batteryUsageStatsBuilder, + BatteryStatsImpl stats, BatteryUsageStatsQuery query, + boolean includeVirtualUids) { + synchronized (stats) { + final List<PowerCalculator> powerCalculators = getPowerCalculators(); + final long realtimeUs = mClock.elapsedRealtime() * 1000; + final long uptimeUs = mClock.uptimeMillis() * 1000; + final int[] powerComponents = query.getPowerComponents(); + SparseArray<? extends BatteryStats.Uid> uidStats = stats.getUidStats(); + for (int i = uidStats.size() - 1; i >= 0; i--) { + final BatteryStats.Uid uid = uidStats.valueAt(i); + if (!includeVirtualUids + && uid.getUid() == Process.SDK_SANDBOX_VIRTUAL_UID) { + continue; + } + + batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid); + } + for (int i = 0, count = powerCalculators.size(); i < count; i++) { + PowerCalculator powerCalculator = powerCalculators.get(i); + if (powerComponents != null) { + boolean include = false; + for (int powerComponent : powerComponents) { + if (powerCalculator.isPowerComponentSupported(powerComponent)) { + include = true; + break; + } + } + if (!include) { + continue; + } + } + powerCalculator.calculate(batteryUsageStatsBuilder, stats, realtimeUs, uptimeUs, + query); + } } } - private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryStatsImpl stats, + private void populateBatterySessionInfo(BatteryUsageStats.Builder builder, + BatteryStatsSession session) { + builder.setBatteryCapacity(session.getEstimatedBatteryCapacity()); + builder.setBatteryTimeRemainingMs(session.getBatteryTimeRemainingMs()); + builder.setChargeTimeRemainingMs(session.getChargeTimeRemainingMs()); + } + + private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryStatsSession stats, BatteryUsageStatsQuery query) { final boolean includeProcessStateData = ((query.getFlags() - & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0) - && stats.isProcessStateDataAvailable(); + & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0); final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold(); final String[] customEnergyConsumerNames = stats.getCustomEnergyConsumerNames(); @@ -539,4 +539,33 @@ public class BatteryUsageStatsProvider { } return builder.build(); } + + private void buildUserBatteryConsumers(BatteryUsageStats.Builder builder, + @UserIdInt int[] userIds) { + if (ArrayUtils.contains(userIds, UserHandle.USER_ALL)) { + return; + } + + SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = + builder.getUidBatteryConsumerBuilders(); + + for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { + final UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i); + if (uidBuilder.isVirtualUid()) { + continue; + } + + final int uid = uidBuilder.getUid(); + if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) { + continue; + } + + final int userId = UserHandle.getUserId(uid); + if (!ArrayUtils.contains(userIds, userId)) { + uidBuilder.excludeFromBatteryUsageStats(); + builder.getOrCreateUserBatteryConsumerBuilder(userId) + .addUidBatteryConsumer(uidBuilder); + } + } + } } diff --git a/services/core/java/com/android/server/power/stats/PowerStatsStore.java b/services/core/java/com/android/server/power/stats/PowerStatsStore.java index b688d4b3ecde..cdf2f25a109f 100644 --- a/services/core/java/com/android/server/power/stats/PowerStatsStore.java +++ b/services/core/java/com/android/server/power/stats/PowerStatsStore.java @@ -205,21 +205,30 @@ public class PowerStatsStore { */ public void storeBatteryUsageStatsAsync(long monotonicStartTime, BatteryUsageStats batteryUsageStats) { - mHandler.post(() -> { + if (mHandler.getLooper().isCurrentThread()) { + storeBatteryUsageStats(monotonicStartTime, batteryUsageStats); + } else { + mHandler.post(() -> { + storeBatteryUsageStats(monotonicStartTime, batteryUsageStats); + }); + } + } + + private void storeBatteryUsageStats(long monotonicStartTime, + BatteryUsageStats batteryUsageStats) { + try { + PowerStatsSpan span = new PowerStatsSpan(monotonicStartTime); + span.addTimeFrame(monotonicStartTime, batteryUsageStats.getStatsStartTimestamp(), + batteryUsageStats.getStatsDuration()); + span.addSection(new BatteryUsageStatsSection(batteryUsageStats)); + storePowerStatsSpan(span); + } finally { try { - PowerStatsSpan span = new PowerStatsSpan(monotonicStartTime); - span.addTimeFrame(monotonicStartTime, batteryUsageStats.getStatsStartTimestamp(), - batteryUsageStats.getStatsDuration()); - span.addSection(new BatteryUsageStatsSection(batteryUsageStats)); - storePowerStatsSpan(span); - } finally { - try { - batteryUsageStats.close(); - } catch (IOException e) { - Slog.e(TAG, "Cannot close BatteryUsageStats", e); - } + batteryUsageStats.close(); + } catch (IOException e) { + Slog.e(TAG, "Cannot close BatteryUsageStats", e); } - }); + } } /** diff --git a/services/core/java/com/android/server/power/stats/UserPowerCalculator.java b/services/core/java/com/android/server/power/stats/UserPowerCalculator.java deleted file mode 100644 index e08d036f125e..000000000000 --- a/services/core/java/com/android/server/power/stats/UserPowerCalculator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import android.os.BatteryConsumer; -import android.os.BatteryStats; -import android.os.BatteryUsageStats; -import android.os.BatteryUsageStatsQuery; -import android.os.Process; -import android.os.UidBatteryConsumer; -import android.os.UserHandle; -import android.util.SparseArray; - -import com.android.internal.util.ArrayUtils; - -/** - * Computes power consumed by Users - */ -public class UserPowerCalculator extends PowerCalculator { - - @Override - public boolean isPowerComponentSupported(@BatteryConsumer.PowerComponent int powerComponent) { - return true; - } - - @Override - public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, - long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { - final int[] userIds = query.getUserIds(); - if (ArrayUtils.contains(userIds, UserHandle.USER_ALL)) { - return; - } - - SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders = - builder.getUidBatteryConsumerBuilders(); - - for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) { - final UidBatteryConsumer.Builder uidBuilder = uidBatteryConsumerBuilders.valueAt(i); - if (uidBuilder.isVirtualUid()) { - continue; - } - - final int uid = uidBuilder.getUid(); - if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) { - continue; - } - - final int userId = UserHandle.getUserId(uid); - if (!ArrayUtils.contains(userIds, userId)) { - uidBuilder.excludeFromBatteryUsageStats(); - builder.getOrCreateUserBatteryConsumerBuilder(userId) - .addUidBatteryConsumer(uidBuilder); - } - } - } -} diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 40ea9319c6be..7f2c68ff60b1 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -118,6 +118,7 @@ import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.display.DisplayManager; import android.hardware.face.FaceManager; import android.hardware.fingerprint.FingerprintManager; +import android.health.connect.HealthConnectManager; import android.media.AudioManager; import android.media.MediaDrm; import android.media.UnsupportedSchemeException; @@ -4115,7 +4116,7 @@ public class StatsPullAtomService extends SystemService { int nOps = opsList.size(); for (int i = 0; i < nOps; i++) { AppOpEntry entry = opsList.get(i); - if (entry.mHash >= samplingRate) { + if (entry.mHash >= samplingRate || isHealthAppOp(entry.mOp.getOpCode())) { continue; } StatsEvent e; @@ -4301,6 +4302,11 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } + if (isHealthAppOp(AppOpsManager.strOpToOp(message.getOp()))) { + // Not log sensitive health app ops. + return StatsManager.PULL_SKIP; + } + pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, message.getUid(), message.getPackageName(), "", message.getAttributionTag() == null ? "" : message.getAttributionTag(), @@ -4893,7 +4899,7 @@ public class StatsPullAtomService extends SystemService { Slog.e(TAG, "Disconnected from keystore service. Cannot pull.", e); return StatsManager.PULL_SKIP; } catch (ServiceSpecificException e) { - Slog.e(TAG, "pulling keystore metrics failed", e); + Slog.e(TAG, "Pulling keystore atom with tag " + atomTag + " failed", e); return StatsManager.PULL_SKIP; } finally { Binder.restoreCallingIdentity(callingToken); @@ -5370,6 +5376,11 @@ public class StatsPullAtomService extends SystemService { } } + private boolean isHealthAppOp(int opCode) { + String permission = AppOpsManager.opToPermission(opCode); + return permission != null && HealthConnectManager.isHealthPermission(mContext, permission); + } + // Thermal event received from vendor thermal management subsystem private static final class ThermalEventListener extends IThermalEventListener.Stub { @Override diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index ae726c15ed79..a5805043ac42 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -79,6 +79,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; import com.android.server.SystemService; import com.android.server.pm.BackgroundUserSoundNotifier; +import com.android.server.pm.UserManagerService; import com.android.server.vibrator.VibrationSession.CallerInfo; import com.android.server.vibrator.VibrationSession.DebugInfo; import com.android.server.vibrator.VibrationSession.Status; @@ -200,7 +201,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { VibratorManagerService.this::shouldCancelOnScreenOffLocked, Status.CANCELLED_BY_SCREEN_OFF); } - } else if (android.multiuser.Flags.addUiForSoundsFromBackgroundUsers() + } else if (UserManagerService.shouldShowNotificationForBackgroundUserSounds() && intent.getAction().equals(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND)) { synchronized (mLock) { maybeClearCurrentAndNextSessionsLocked( @@ -324,7 +325,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); - if (android.multiuser.Flags.addUiForSoundsFromBackgroundUsers()) { + if (UserManagerService.shouldShowNotificationForBackgroundUserSounds()) { filter.addAction(BackgroundUserSoundNotifier.ACTION_MUTE_SOUND); } context.registerReceiver(mIntentReceiver, filter, Context.RECEIVER_NOT_EXPORTED); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index beec42ed616d..0226650ec560 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -364,6 +364,7 @@ import com.android.internal.content.ReferrerIntent; import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TransferPipe; import com.android.internal.policy.AttributeCache; +import com.android.internal.policy.PhoneWindow; import com.android.internal.protolog.ProtoLog; import com.android.internal.util.XmlUtils; import com.android.modules.utils.TypedXmlPullParser; @@ -2025,8 +2026,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A || ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false); mStyleFillsParent = mOccludesParent; mNoDisplay = ent.array.getBoolean(R.styleable.Window_windowNoDisplay, false); - mOptOutEdgeToEdge = ent.array.getBoolean( - R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false); + mOptOutEdgeToEdge = PhoneWindow.isOptingOutEdgeToEdgeEnforcement( + aInfo.applicationInfo, false /* local */, ent.array); } else { mStyleFillsParent = mOccludesParent = true; mNoDisplay = false; @@ -5476,7 +5477,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean canAffectSystemUiFlags() { - return task != null && task.canAffectSystemUiFlags() && isVisible() + final TaskFragment taskFragment = getTaskFragment(); + return taskFragment != null && taskFragment.canAffectSystemUiFlags() + && isVisible() && !mWaitForEnteringPinnedMode && !inPinnedWindowingMode(); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 9e2c00e6603c..7321f28e4fcd 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -77,7 +77,6 @@ import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_FOCUS; import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_IMMERSIVE; import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_LOCKTASK; import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS; -import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext; import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; import static com.android.server.am.ActivityManagerServiceDumpActivitiesProto.ROOT_WINDOW_CONTAINER; import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE; @@ -1269,10 +1268,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } static boolean isSdkSandboxActivityIntent(Context context, Intent intent) { - return intent != null - && (sandboxActivitySdkBasedContext() - ? SdkSandboxActivityAuthority.isSdkSandboxActivityIntent(context, intent) - : intent.isSandboxActivity(context)); + return SdkSandboxActivityAuthority.isSdkSandboxActivityIntent(context, intent); } private int startActivityAsUser(IApplicationThread caller, String callingPackage, diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 12c8f9ccac7c..906befc1edcc 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1664,6 +1664,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { activityIdleInternal(null /* idleActivity */, false /* fromTimeout */, true /* processPausingActivities */, null /* configuration */); + if (rootTask.getParent() == null) { + // The activities in the task may already be finishing. Then the task could be removed + // when performing the idle check. + return; + } + // Reparent all the tasks to the bottom of the display final DisplayContent toDisplay = mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY); diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java index a94f6252cd68..cc9cd90fae06 100644 --- a/services/core/java/com/android/server/wm/AppCompatController.java +++ b/services/core/java/com/android/server/wm/AppCompatController.java @@ -39,7 +39,7 @@ class AppCompatController { @NonNull private final AppCompatOverrides mAppCompatOverrides; @NonNull - private final AppCompatDeviceStateQuery mAppCompatDeviceStateQuery; + private final AppCompatDeviceStateQuery mDeviceStateQuery; @NonNull private final AppCompatLetterboxPolicy mAppCompatLetterboxPolicy; @NonNull @@ -50,11 +50,11 @@ class AppCompatController { final PackageManager packageManager = wmService.mContext.getPackageManager(); final OptPropFactory optPropBuilder = new OptPropFactory(packageManager, activityRecord.packageName); - mAppCompatDeviceStateQuery = new AppCompatDeviceStateQuery(activityRecord); + mDeviceStateQuery = new AppCompatDeviceStateQuery(activityRecord); mTransparentPolicy = new TransparentPolicy(activityRecord, wmService.mAppCompatConfiguration); mAppCompatOverrides = new AppCompatOverrides(activityRecord, packageManager, - wmService.mAppCompatConfiguration, optPropBuilder, mAppCompatDeviceStateQuery); + wmService.mAppCompatConfiguration, optPropBuilder, mDeviceStateQuery); mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord, mAppCompatOverrides); mAspectRatioPolicy = new AppCompatAspectRatioPolicy(activityRecord, mTransparentPolicy, mAppCompatOverrides); @@ -129,8 +129,8 @@ class AppCompatController { } @NonNull - AppCompatDeviceStateQuery getAppCompatDeviceStateQuery() { - return mAppCompatDeviceStateQuery; + AppCompatDeviceStateQuery getDeviceStateQuery() { + return mDeviceStateQuery; } @NonNull diff --git a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java index 087edc184b6f..a7c52bd1fc38 100644 --- a/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatReachabilityPolicy.java @@ -107,7 +107,7 @@ class AppCompatReachabilityPolicy { return; } final AppCompatDeviceStateQuery deviceStateQuery = mActivityRecord.mAppCompatController - .getAppCompatDeviceStateQuery(); + .getDeviceStateQuery(); final boolean isInFullScreenBookMode = deviceStateQuery .isDisplayFullScreenAndSeparatingHinge() && mAppCompatConfiguration.getIsAutomaticReachabilityInBookModeEnabled(); @@ -153,7 +153,7 @@ class AppCompatReachabilityPolicy { return; } final AppCompatDeviceStateQuery deviceStateQuery = mActivityRecord.mAppCompatController - .getAppCompatDeviceStateQuery(); + .getDeviceStateQuery(); final boolean isInFullScreenTabletopMode = deviceStateQuery .isDisplayFullScreenAndSeparatingHinge(); final int letterboxPositionForVerticalReachability = mAppCompatConfiguration diff --git a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java index f48ef4fa8f5f..c6831881ea48 100644 --- a/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java +++ b/services/core/java/com/android/server/wm/AppCompatSizeCompatModePolicy.java @@ -228,7 +228,10 @@ class AppCompatSizeCompatModePolicy { int rotation = newParentConfiguration.windowConfiguration.getRotation(); final boolean isFixedToUserRotation = mActivityRecord.mDisplayContent == null || mActivityRecord.mDisplayContent.getDisplayRotation().isFixedToUserRotation(); - if (!isFixedToUserRotation && !appCompatDisplayInsets.mIsFloating) { + // Ignore parent rotation for floating tasks as window rotation is independent of its parent + // and thus will remain, and so should be reconfigured, in its original rotation. + if (!isFixedToUserRotation + && !newParentConfiguration.windowConfiguration.tasksAreFloating()) { // Use parent rotation because the original display can be rotated. resolvedConfig.windowConfiguration.setRotation(rotation); } else { diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java index 601b17c46c03..576e5d5d0cd2 100644 --- a/services/core/java/com/android/server/wm/AppWarnings.java +++ b/services/core/java/com/android/server/wm/AppWarnings.java @@ -51,6 +51,7 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import android.view.ContextThemeWrapper; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; @@ -498,10 +499,21 @@ class AppWarnings { } } if (!hasPackageFlag(userId, ar.packageName, FLAG_HIDE_PAGE_SIZE_MISMATCH)) { + Context context = getUiContextForActivity(ar); + // PageSizeMismatchDialog has link in message which should open in browser. + // Starting activity from non-activity context is not allowed and flag + // FLAG_ACTIVITY_NEW_TASK is needed to start activity. + context = new ContextThemeWrapper(context, context.getThemeResId()) { + @Override + public void startActivity(Intent intent) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + super.startActivity(intent); + } + }; pageSizeMismatchDialog = new PageSizeMismatchDialog( AppWarnings.this, - getUiContextForActivity(ar), + context, ar.info.applicationInfo, userId, warning); diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java index 5bec4424269a..4b30a43db5d9 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java @@ -53,6 +53,12 @@ import java.util.List; * Policy that manages {@link DisplayArea}. */ public abstract class DisplayAreaPolicy { + /** + * No corresponding use case yet (see b/154719717). The current implementation still uses + * {@link WindowState#shouldMagnify}. + */ + static final boolean USE_DISPLAY_AREA_FOR_FULLSCREEN_MAGNIFICATION = false; + protected final WindowManagerService mWmService; /** @@ -161,14 +167,17 @@ public abstract class DisplayAreaPolicy { TYPE_STATUS_BAR, TYPE_NOTIFICATION_SHADE, TYPE_WALLPAPER) .build()); } + if (USE_DISPLAY_AREA_FOR_FULLSCREEN_MAGNIFICATION) { + rootHierarchy.addFeature( + new Feature.Builder(wmService.mPolicy, "FullscreenMagnification", + FEATURE_FULLSCREEN_MAGNIFICATION) + .all() + .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD, + TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY, + TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL) + .build()); + } rootHierarchy - .addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification", - FEATURE_FULLSCREEN_MAGNIFICATION) - .all() - .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD, - TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY, - TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL) - .build()) .addFeature(new Feature.Builder(wmService.mPolicy, "ImePlaceholder", FEATURE_IME_PLACEHOLDER) .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 01e00e9d67f7..999666e22985 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -22,7 +22,6 @@ import static android.view.InsetsFrameProvider.SOURCE_ARBITRARY_RECTANGLE; import static android.view.InsetsFrameProvider.SOURCE_CONTAINER_BOUNDS; import static android.view.InsetsFrameProvider.SOURCE_DISPLAY; import static android.view.InsetsFrameProvider.SOURCE_FRAME; -import static android.view.ViewRootImpl.CLIENT_IMMERSIVE_CONFIRMATION; import static android.view.ViewRootImpl.CLIENT_TRANSIENT; import static android.view.WindowInsetsController.APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; @@ -193,7 +192,6 @@ public class DisplayPolicy { private final boolean mCarDockEnablesAccelerometer; private final boolean mDeskDockEnablesAccelerometer; private final AccessibilityManager mAccessibilityManager; - private final ImmersiveModeConfirmation mImmersiveModeConfirmation; private final ScreenshotHelper mScreenshotHelper; private final Object mServiceAcquireLock = new Object(); @@ -634,12 +632,6 @@ public class DisplayPolicy { }; displayContent.mAppTransition.registerListenerLocked(mAppTransitionListener); displayContent.mTransitionController.registerLegacyListener(mAppTransitionListener); - if (CLIENT_TRANSIENT || CLIENT_IMMERSIVE_CONFIRMATION) { - mImmersiveModeConfirmation = null; - } else { - mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper, - mService.mVrModeEnabled, mCanSystemBarsBeShownByUser); - } // TODO: Make it can take screenshot on external display mScreenshotHelper = displayContent.isDefaultDisplay @@ -2294,11 +2286,7 @@ public class DisplayPolicy { } } } - if (CLIENT_IMMERSIVE_CONFIRMATION || CLIENT_TRANSIENT) { - mStatusBarManagerInternal.confirmImmersivePrompt(); - } else { - mImmersiveModeConfirmation.confirmCurrentPrompt(); - } + mStatusBarManagerInternal.confirmImmersivePrompt(); } boolean isKeyguardShowing() { @@ -2523,16 +2511,9 @@ public class DisplayPolicy { // The immersive confirmation window should be attached to the immersive window root. final RootDisplayArea root = win.getRootDisplayArea(); final int rootDisplayAreaId = root == null ? FEATURE_UNDEFINED : root.mFeatureId; - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - mImmersiveModeConfirmation.immersiveModeChangedLw(rootDisplayAreaId, - isImmersiveMode, - mService.mPolicy.isUserSetupComplete(), - isNavBarEmpty(disableFlags)); - } else { - // TODO(b/277290737): Move this to the client side, instead of using a proxy. - callStatusBarSafely(statusBar -> statusBar.immersiveModeChanged(getDisplayId(), + // TODO(b/277290737): Move this to the client side, instead of using a proxy. + callStatusBarSafely(statusBar -> statusBar.immersiveModeChanged(getDisplayId(), rootDisplayAreaId, isImmersiveMode)); - } } // Show transient bars for panic if needed. @@ -2745,15 +2726,8 @@ public class DisplayPolicy { void onPowerKeyDown(boolean isScreenOn) { // Detect user pressing the power button in panic when an application has // taken over the whole screen. - boolean panic = false; - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - panic = mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn, - SystemClock.elapsedRealtime(), isImmersiveMode(mSystemUiControllingWindow), - isNavBarEmpty(mLastDisableFlags)); - } else { - panic = isPowerKeyDownPanic(isScreenOn, SystemClock.elapsedRealtime(), + boolean panic = isPowerKeyDownPanic(isScreenOn, SystemClock.elapsedRealtime(), isImmersiveMode(mSystemUiControllingWindow), isNavBarEmpty(mLastDisableFlags)); - } if (panic) { mHandler.post(mHiddenNavPanic); } @@ -2774,27 +2748,6 @@ public class DisplayPolicy { return false; } - void onVrStateChangedLw(boolean enabled) { - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - mImmersiveModeConfirmation.onVrStateChangedLw(enabled); - } - } - - /** - * Called when the state of lock task mode changes. This should be used to disable immersive - * mode confirmation. - * - * @param lockTaskState the new lock task mode state. One of - * {@link ActivityManager#LOCK_TASK_MODE_NONE}, - * {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, - * {@link ActivityManager#LOCK_TASK_MODE_PINNED}. - */ - public void onLockTaskStateChangedLw(int lockTaskState) { - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - mImmersiveModeConfirmation.onLockTaskModeChangedLw(lockTaskState); - } - } - /** Called when a {@link android.os.PowerManager#USER_ACTIVITY_EVENT_TOUCH} is sent. */ public void onUserActivityEventTouch() { // If there is keyguard, it may use INPUT_FEATURE_DISABLE_USER_ACTIVITY (InputDispatcher @@ -2808,14 +2761,6 @@ public class DisplayPolicy { mService.mAtmService.setProcessAnimatingWhileDozing(w != null ? w.getProcess() : null); } - boolean onSystemUiSettingsChanged() { - if (CLIENT_TRANSIENT || CLIENT_IMMERSIVE_CONFIRMATION) { - return false; - } else { - return mImmersiveModeConfirmation.onSettingChanged(mService.mCurrentUserId); - } - } - /** * Request a screenshot be taken. * @@ -3025,9 +2970,6 @@ public class DisplayPolicy { mDisplayContent.mTransitionController.unregisterLegacyListener(mAppTransitionListener); mHandler.post(mGestureNavigationSettingsObserver::unregister); mHandler.post(mForceShowNavBarSettingsObserver::unregister); - if (!CLIENT_TRANSIENT && !CLIENT_IMMERSIVE_CONFIRMATION) { - mImmersiveModeConfirmation.release(); - } if (mService.mPointerLocationEnabled) { setPointerLocationEnabled(false); } diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java index fa748d3a22a5..c418349e6158 100644 --- a/services/core/java/com/android/server/wm/DragDropController.java +++ b/services/core/java/com/android/server/wm/DragDropController.java @@ -28,9 +28,11 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.content.ClipData; import android.content.Context; +import android.hardware.display.DisplayTopology; import android.hardware.input.InputManagerGlobal; import android.os.Binder; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.IBinder; import android.os.Looper; import android.os.Message; @@ -50,12 +52,14 @@ import android.window.IUnhandledDragCallback; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wm.WindowManagerInternal.IDragDropCallback; +import com.android.window.flags.Flags; import java.util.Objects; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; /** * Managing drag and drop operations initiated by View#startDragAndDrop. @@ -83,6 +87,8 @@ class DragDropController { private WindowManagerService mService; private final Handler mHandler; + private final Consumer<DisplayTopology> mDisplayTopologyListener = + this::handleDisplayTopologyChange; // The global drag listener for handling cross-window drags private IGlobalDragListener mGlobalDragListener; @@ -108,6 +114,10 @@ class DragDropController { DragDropController(WindowManagerService service, Looper looper) { mService = service; mHandler = new DragHandler(service, looper); + if (Flags.enableConnectedDisplaysDnd()) { + mService.mDisplayManager.registerTopologyListener( + new HandlerExecutor(mService.mH), mDisplayTopologyListener); + } } @VisibleForTesting @@ -481,6 +491,19 @@ class DragDropController { } } + @VisibleForTesting + void handleDisplayTopologyChange(DisplayTopology unused) { + synchronized (mService.mGlobalLock) { + if (mDragState == null) { + return; + } + if (DEBUG_DRAG) { + Slog.d(TAG_WM, "DisplayTopology changed, cancelling DragAndDrop"); + } + cancelDragAndDrop(mDragState.mToken, true /* skipAnimation */); + } + } + /** * Handles motion events. * @param keepHandling Whether if the drag operation is continuing or this is the last motion diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java index 02a7db19f405..0fbf56d120a8 100644 --- a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java +++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java @@ -77,8 +77,9 @@ class EmulatorDisplayOverlay { mOverlay = context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay); - mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, mScreenSize.x, - mScreenSize.y, PixelFormat.RGBA_8888); + mBlastBufferQueue = new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true); + mBlastBufferQueue.update(mSurfaceControl, mScreenSize.x, mScreenSize.y, + PixelFormat.RGBA_8888); mSurface = mBlastBufferQueue.createSurface(); } diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags index 9d6688648021..5767db1461d0 100644 --- a/services/core/java/com/android/server/wm/EventLogTags.logtags +++ b/services/core/java/com/android/server/wm/EventLogTags.logtags @@ -69,7 +69,7 @@ option java_package com.android.server.wm # bootanim finished: 31007 wm_boot_animation_done (time|2|3) -# Notify keyguard occlude statuc change to SysUI. +# Notify keyguard occlude status change to SysUI. 31008 wm_set_keyguard_occluded (occluded|1),(animate|1),(transit|1),(Channel|3) # Back navigation. diff --git a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java deleted file mode 100644 index d79c11cecdc0..000000000000 --- a/services/core/java/com/android/server/wm/ImmersiveModeConfirmation.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; -import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.ViewRootImpl.CLIENT_TRANSIENT; -import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; -import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; -import static android.window.DisplayAreaOrganizer.KEY_ROOT_DISPLAY_AREA_ID; - -import android.animation.ArgbEvaluator; -import android.animation.ValueAnimator; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.ActivityManager; -import android.app.ActivityThread; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.Insets; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; -import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import android.util.DisplayMetrics; -import android.util.Slog; -import android.view.Display; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewTreeObserver; -import android.view.WindowInsets; -import android.view.WindowInsets.Type; -import android.view.WindowManager; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.widget.Button; -import android.widget.FrameLayout; -import android.widget.RelativeLayout; - -import com.android.internal.R; - -/** - * Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden - * entering immersive mode. - */ -public class ImmersiveModeConfirmation { - private static final String TAG = "ImmersiveModeConfirmation"; - private static final boolean DEBUG = false; - private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution - private static final String CONFIRMED = "confirmed"; - private static final int IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE = - WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; - - private static boolean sConfirmed; - - private final Context mContext; - private final H mHandler; - private final long mShowDelayMs; - private final long mPanicThresholdMs; - private final IBinder mWindowToken = new Binder(); - - private ClingWindowView mClingWindow; - private long mPanicTime; - /** The last {@link WindowManager} that is used to add the confirmation window. */ - @Nullable - private WindowManager mWindowManager; - /** - * The WindowContext that is registered with {@link #mWindowManager} with options to specify the - * {@link RootDisplayArea} to attach the confirmation window. - */ - @Nullable - private Context mWindowContext; - /** - * The root display area feature id that the {@link #mWindowContext} is attaching to. - */ - private int mWindowContextRootDisplayAreaId = FEATURE_UNDEFINED; - // Local copy of vr mode enabled state, to avoid calling into VrManager with - // the lock held. - private boolean mVrModeEnabled; - private boolean mCanSystemBarsBeShownByUser; - private int mLockTaskState = LOCK_TASK_MODE_NONE; - - ImmersiveModeConfirmation(Context context, Looper looper, boolean vrModeEnabled, - boolean canSystemBarsBeShownByUser) { - final Display display = context.getDisplay(); - final Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext(); - mContext = display.getDisplayId() == DEFAULT_DISPLAY - ? uiContext : uiContext.createDisplayContext(display); - mHandler = new H(looper); - mShowDelayMs = context.getResources().getInteger(R.integer.dock_enter_exit_duration) * 3L; - mPanicThresholdMs = context.getResources() - .getInteger(R.integer.config_immersive_mode_confirmation_panic); - mVrModeEnabled = vrModeEnabled; - mCanSystemBarsBeShownByUser = canSystemBarsBeShownByUser; - } - - static boolean loadSetting(int currentUserId, Context context) { - final boolean wasConfirmed = sConfirmed; - sConfirmed = false; - if (DEBUG) Slog.d(TAG, String.format("loadSetting() currentUserId=%d", currentUserId)); - String value = null; - try { - value = Settings.Secure.getStringForUser(context.getContentResolver(), - Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS, - UserHandle.USER_CURRENT); - sConfirmed = CONFIRMED.equals(value); - if (DEBUG) Slog.d(TAG, "Loaded sConfirmed=" + sConfirmed); - } catch (Throwable t) { - Slog.w(TAG, "Error loading confirmations, value=" + value, t); - } - return sConfirmed != wasConfirmed; - } - - private static void saveSetting(Context context) { - if (DEBUG) Slog.d(TAG, "saveSetting()"); - try { - final String value = sConfirmed ? CONFIRMED : null; - Settings.Secure.putStringForUser(context.getContentResolver(), - Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS, - value, - UserHandle.USER_CURRENT); - if (DEBUG) Slog.d(TAG, "Saved value=" + value); - } catch (Throwable t) { - Slog.w(TAG, "Error saving confirmations, sConfirmed=" + sConfirmed, t); - } - } - - void release() { - mHandler.removeMessages(H.SHOW); - mHandler.removeMessages(H.HIDE); - } - - boolean onSettingChanged(int currentUserId) { - final boolean changed = loadSetting(currentUserId, mContext); - // Remove the window if the setting changes to be confirmed. - if (changed && sConfirmed) { - mHandler.sendEmptyMessage(H.HIDE); - } - return changed; - } - - void immersiveModeChangedLw(int rootDisplayAreaId, boolean isImmersiveMode, - boolean userSetupComplete, boolean navBarEmpty) { - mHandler.removeMessages(H.SHOW); - if (isImmersiveMode) { - if (DEBUG) Slog.d(TAG, "immersiveModeChanged() sConfirmed=" + sConfirmed); - if ((DEBUG_SHOW_EVERY_TIME || !sConfirmed) - && userSetupComplete - && !mVrModeEnabled - && mCanSystemBarsBeShownByUser - && !navBarEmpty - && !UserManager.isDeviceInDemoMode(mContext) - && (mLockTaskState != LOCK_TASK_MODE_LOCKED)) { - final Message msg = mHandler.obtainMessage(H.SHOW); - msg.arg1 = rootDisplayAreaId; - mHandler.sendMessageDelayed(msg, mShowDelayMs); - } - } else { - mHandler.sendEmptyMessage(H.HIDE); - } - } - - boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode, - boolean navBarEmpty) { - if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) { - // turning the screen back on within the panic threshold - return mClingWindow == null; - } - if (isScreenOn && inImmersiveMode && !navBarEmpty) { - // turning the screen off, remember if we were in immersive mode - mPanicTime = time; - } else { - mPanicTime = 0; - } - return false; - } - - void confirmCurrentPrompt() { - if (mClingWindow != null) { - if (DEBUG) Slog.d(TAG, "confirmCurrentPrompt()"); - mHandler.post(mConfirm); - } - } - - private void handleHide() { - if (mClingWindow != null) { - if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation"); - if (mWindowManager != null) { - try { - mWindowManager.removeView(mClingWindow); - } catch (WindowManager.InvalidDisplayException e) { - Slog.w(TAG, "Fail to hide the immersive confirmation window because of " - + e); - } - mWindowManager = null; - mWindowContext = null; - } - mClingWindow = null; - } - } - - private WindowManager.LayoutParams getClingWindowLayoutParams() { - final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, - PixelFormat.TRANSLUCENT); - lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~Type.statusBars()); - lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - // Trusted overlay so touches outside the touchable area are allowed to pass through - lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS - | WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY - | WindowManager.LayoutParams.PRIVATE_FLAG_IMMERSIVE_CONFIRMATION_WINDOW; - lp.setTitle("ImmersiveModeConfirmation"); - lp.windowAnimations = com.android.internal.R.style.Animation_ImmersiveModeConfirmation; - lp.token = getWindowToken(); - return lp; - } - - private FrameLayout.LayoutParams getBubbleLayoutParams() { - return new FrameLayout.LayoutParams( - getClingWindowWidth(), - ViewGroup.LayoutParams.WRAP_CONTENT, - Gravity.CENTER_HORIZONTAL | Gravity.TOP); - } - - /** - * Returns the width of the cling window. - */ - private int getClingWindowWidth() { - return mContext.getResources().getDimensionPixelSize( - R.dimen.immersive_mode_cling_width); - } - - /** - * @return the window token that's used by all ImmersiveModeConfirmation windows. - */ - IBinder getWindowToken() { - return mWindowToken; - } - - private class ClingWindowView extends FrameLayout { - private static final int BGCOLOR = 0x80000000; - private static final int OFFSET_DP = 96; - private static final int ANIMATION_DURATION = 250; - - private final Runnable mConfirm; - private final ColorDrawable mColor = new ColorDrawable(0); - private final Interpolator mInterpolator; - private ValueAnimator mColorAnim; - private ViewGroup mClingLayout; - - private Runnable mUpdateLayoutRunnable = new Runnable() { - @Override - public void run() { - if (mClingLayout != null && mClingLayout.getParent() != null) { - mClingLayout.setLayoutParams(getBubbleLayoutParams()); - } - } - }; - - private ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = - new ViewTreeObserver.OnComputeInternalInsetsListener() { - private final int[] mTmpInt2 = new int[2]; - - @Override - public void onComputeInternalInsets( - ViewTreeObserver.InternalInsetsInfo inoutInfo) { - // Set touchable region to cover the cling layout. - mClingLayout.getLocationInWindow(mTmpInt2); - inoutInfo.setTouchableInsets( - ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); - inoutInfo.touchableRegion.set( - mTmpInt2[0], - mTmpInt2[1], - mTmpInt2[0] + mClingLayout.getWidth(), - mTmpInt2[1] + mClingLayout.getHeight()); - } - }; - - private BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) { - post(mUpdateLayoutRunnable); - } - } - }; - - ClingWindowView(Context context, Runnable confirm) { - super(context); - mConfirm = confirm; - setBackground(mColor); - setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO); - mInterpolator = AnimationUtils - .loadInterpolator(mContext, android.R.interpolator.linear_out_slow_in); - } - - @Override - public void onAttachedToWindow() { - super.onAttachedToWindow(); - - DisplayMetrics metrics = new DisplayMetrics(); - mContext.getDisplay().getMetrics(metrics); - float density = metrics.density; - - getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener); - - // create the confirmation cling - mClingLayout = (ViewGroup) - View.inflate(getContext(), R.layout.immersive_mode_cling, null); - - final Button ok = mClingLayout.findViewById(R.id.ok); - ok.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - mConfirm.run(); - } - }); - addView(mClingLayout, getBubbleLayoutParams()); - - if (ActivityManager.isHighEndGfx()) { - final View cling = mClingLayout; - cling.setAlpha(0f); - cling.setTranslationY(-OFFSET_DP * density); - - postOnAnimation(new Runnable() { - @Override - public void run() { - cling.animate() - .alpha(1f) - .translationY(0) - .setDuration(ANIMATION_DURATION) - .setInterpolator(mInterpolator) - .withLayer() - .start(); - - mColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(), 0, BGCOLOR); - mColorAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - final int c = (Integer) animation.getAnimatedValue(); - mColor.setColor(c); - } - }); - mColorAnim.setDuration(ANIMATION_DURATION); - mColorAnim.setInterpolator(mInterpolator); - mColorAnim.start(); - } - }); - } else { - mColor.setColor(BGCOLOR); - } - - mContext.registerReceiver(mReceiver, - new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED)); - } - - @Override - public void onDetachedFromWindow() { - mContext.unregisterReceiver(mReceiver); - } - - @Override - public boolean onTouchEvent(MotionEvent motion) { - return true; - } - - @Override - public WindowInsets onApplyWindowInsets(WindowInsets insets) { - // If the top display cutout overlaps with the full-width (windowWidth=-1)/centered - // dialog, then adjust the dialog contents by the cutout - final int width = getWidth(); - final int windowWidth = getClingWindowWidth(); - final Rect topDisplayCutout = insets.getDisplayCutout() != null - ? insets.getDisplayCutout().getBoundingRectTop() - : new Rect(); - final boolean intersectsTopCutout = topDisplayCutout.intersects( - width - (windowWidth / 2), 0, - width + (windowWidth / 2), topDisplayCutout.bottom); - if (windowWidth < 0 || (width > 0 && intersectsTopCutout)) { - final View iconView = findViewById(R.id.immersive_cling_icon); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) - iconView.getLayoutParams(); - lp.topMargin = topDisplayCutout.bottom; - iconView.setLayoutParams(lp); - } - // we will be hiding the nav bar, so layout as if it's already hidden - return new WindowInsets.Builder(insets).setInsets( - Type.systemBars(), Insets.NONE).build(); - } - } - - /** - * DO HOLD THE WINDOW MANAGER LOCK WHEN CALLING THIS METHOD - * The reason why we add this method is to avoid the deadlock of WMG->WMS and WMS->WMG - * when ImmersiveModeConfirmation object is created. - * - * @return the WindowManager specifying with the {@code rootDisplayAreaId} to attach the - * confirmation window. - */ - @NonNull - private WindowManager createWindowManager(int rootDisplayAreaId) { - if (mWindowManager != null) { - throw new IllegalStateException( - "Must not create a new WindowManager while there is an existing one"); - } - // Create window context to specify the RootDisplayArea - final Bundle options = getOptionsForWindowContext(rootDisplayAreaId); - mWindowContextRootDisplayAreaId = rootDisplayAreaId; - mWindowContext = mContext.createWindowContext( - IMMERSIVE_MODE_CONFIRMATION_WINDOW_TYPE, options); - mWindowManager = mWindowContext.getSystemService(WindowManager.class); - return mWindowManager; - } - - /** - * Returns options that specify the {@link RootDisplayArea} to attach the confirmation window. - * {@code null} if the {@code rootDisplayAreaId} is {@link FEATURE_UNDEFINED}. - */ - @Nullable - private Bundle getOptionsForWindowContext(int rootDisplayAreaId) { - // In case we don't care which root display area the window manager is specifying. - if (rootDisplayAreaId == FEATURE_UNDEFINED) { - return null; - } - - final Bundle options = new Bundle(); - options.putInt(KEY_ROOT_DISPLAY_AREA_ID, rootDisplayAreaId); - return options; - } - - private void handleShow(int rootDisplayAreaId) { - if (mClingWindow != null) { - if (rootDisplayAreaId == mWindowContextRootDisplayAreaId) { - if (DEBUG) Slog.d(TAG, "Immersive mode confirmation has already been shown"); - return; - } else { - // Hide the existing confirmation before show a new one in the new root. - if (DEBUG) Slog.d(TAG, "Immersive mode confirmation was shown in a different root"); - handleHide(); - } - } - - if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation"); - mClingWindow = new ClingWindowView(mContext, mConfirm); - // show the confirmation - final WindowManager.LayoutParams lp = getClingWindowLayoutParams(); - try { - createWindowManager(rootDisplayAreaId).addView(mClingWindow, lp); - } catch (WindowManager.InvalidDisplayException e) { - Slog.w(TAG, "Fail to show the immersive confirmation window because of " + e); - } - } - - private final Runnable mConfirm = new Runnable() { - @Override - public void run() { - if (DEBUG) Slog.d(TAG, "mConfirm.run()"); - if (!sConfirmed) { - sConfirmed = true; - saveSetting(mContext); - } - handleHide(); - } - }; - - private final class H extends Handler { - private static final int SHOW = 1; - private static final int HIDE = 2; - - H(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - if (CLIENT_TRANSIENT) { - return; - } - switch(msg.what) { - case SHOW: - handleShow(msg.arg1); - break; - case HIDE: - handleHide(); - break; - } - } - } - - void onVrStateChangedLw(boolean enabled) { - mVrModeEnabled = enabled; - if (mVrModeEnabled) { - mHandler.removeMessages(H.SHOW); - mHandler.sendEmptyMessage(H.HIDE); - } - } - - void onLockTaskModeChangedLw(int lockTaskState) { - mLockTaskState = lockTaskState; - } -} diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 790858d2eec2..b3eccdbc2452 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -609,7 +609,6 @@ public class LockTaskController { statusBarService.showPinningEnterExitToast(false /* entering */); } } - mWindowManager.onLockTaskStateChanged(mLockTaskModeState); } catch (RemoteException ex) { throw new RuntimeException(ex); } @@ -745,7 +744,6 @@ public class LockTaskController { statusBarService.showPinningEnterExitToast(true /* entering */); } } - mWindowManager.onLockTaskStateChanged(lockTaskModeState); mLockTaskModeState = lockTaskModeState; mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState); setStatusBarState(lockTaskModeState, userId); diff --git a/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java b/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java index 29922f0f85c5..24235ef2d585 100644 --- a/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java +++ b/services/core/java/com/android/server/wm/PageSizeMismatchDialog.java @@ -24,8 +24,10 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.text.Html; +import android.text.method.LinkMovementMethod; import android.view.Window; import android.view.WindowManager; +import android.widget.TextView; import com.android.internal.R; @@ -69,6 +71,14 @@ class PageSizeMismatchDialog extends AppWarnings.BaseDialog { mDialog.create(); final Window window = mDialog.getWindow(); - window.setType(WindowManager.LayoutParams.TYPE_PHONE); + window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); + } + + @Override + public void show() { + super.show(); + // Make the links in dialog clickable + final TextView msgTxt = (TextView) mDialog.findViewById(android.R.id.message); + msgTxt.setMovementMethod(LinkMovementMethod.getInstance()); } } diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index 44f000da3d73..b9550feeab8a 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -40,7 +40,6 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static com.android.internal.protolog.WmProtoLogGroups.WM_DEBUG_TASKS; -import static com.android.launcher3.Flags.enableUseTopVisibleActivityForExcludeFromRecentTask; import static com.android.server.wm.ActivityRecord.State.RESUMED; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS; @@ -1528,12 +1527,7 @@ class RecentTasks { } // The Recents is only supported on default display now, we should only keep the // most recent task of home display. - boolean isMostRecentTask; - if (enableUseTopVisibleActivityForExcludeFromRecentTask()) { - isMostRecentTask = task.getTopVisibleActivity() != null; - } else { - isMostRecentTask = taskIndex == 0; - } + boolean isMostRecentTask = task.getTopVisibleActivity() != null; return (task.isOnHomeDisplay() && isMostRecentTask); } } diff --git a/services/core/java/com/android/server/wm/StrictModeFlash.java b/services/core/java/com/android/server/wm/StrictModeFlash.java index cdf6b08b1c57..b6365ad47535 100644 --- a/services/core/java/com/android/server/wm/StrictModeFlash.java +++ b/services/core/java/com/android/server/wm/StrictModeFlash.java @@ -63,8 +63,9 @@ class StrictModeFlash { mSurfaceControl = ctrl; mDrawNeeded = true; - mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, 1 /* width */, - 1 /* height */, PixelFormat.RGBA_8888); + mBlastBufferQueue = new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true); + mBlastBufferQueue.update(mSurfaceControl, 1 /* width */, 1 /* height */, + PixelFormat.RGBA_8888); mSurface = mBlastBufferQueue.createSurface(); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index fe478c60bc32..7a88338d8ac5 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -468,9 +468,6 @@ class Task extends TaskFragment { // NOTE: This value needs to be persisted with each task private TaskDescription mTaskDescription; - /** @see #setCanAffectSystemUiFlags */ - private boolean mCanAffectSystemUiFlags = true; - private static Exception sTmpException; private boolean mForceShowForAllUsers; @@ -3288,21 +3285,6 @@ class Task extends TaskFragment { return isRootTask() && callback.test(this) ? this : null; } - /** - * @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI - * flags. See {@link WindowState#canAffectSystemUiFlags()}. - */ - void setCanAffectSystemUiFlags(boolean canAffectSystemUiFlags) { - mCanAffectSystemUiFlags = canAffectSystemUiFlags; - } - - /** - * @see #setCanAffectSystemUiFlags - */ - boolean canAffectSystemUiFlags() { - return mCanAffectSystemUiFlags; - } - void dontAnimateDimExit() { mDimmer.dontAnimateExit(); } @@ -5315,40 +5297,29 @@ class Task extends TaskFragment { return mRootWindowContainer.resumeHomeActivity(prev, reason, getDisplayArea()); } - void startActivityLocked(ActivityRecord r, @Nullable Task topTask, boolean newTask, - boolean isTaskSwitch, ActivityOptions options, @Nullable ActivityRecord sourceRecord) { - Task rTask = r.getTask(); + void startActivityLocked(@NonNull ActivityRecord r, @Nullable Task topTask, boolean newTask, + boolean isTaskSwitch, @Nullable ActivityOptions options, + @Nullable ActivityRecord sourceRecord) { final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront(); - final boolean isOrhasTask = rTask == this || hasChild(rTask); + final Task activityTask = r.getTask(); + final boolean isThisOrHasChildTask = activityTask == this || hasChild(activityTask); + // mLaunchTaskBehind tasks get placed at the back of the task stack. - if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) { + if (!r.mLaunchTaskBehind && allowMoveToFront && (!isThisOrHasChildTask || newTask)) { // Last activity in task had been removed or ActivityManagerService is reusing task. // Insert or replace. // Might not even be in. - positionChildAtTop(rTask); + positionChildAtTop(activityTask); } - Task task = null; - if (!newTask && isOrhasTask && !r.shouldBeVisible()) { + + if (!newTask && isThisOrHasChildTask && !r.shouldBeVisible()) { ActivityOptions.abort(options); return; } - // Place a new activity at top of root task, so it is next to interact with the user. - - // If we are not placing the new activity frontmost, we do not want to deliver the - // onUserLeaving callback to the actual frontmost activity - final Task activityTask = r.getTask(); - if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) { - mTaskSupervisor.mUserLeaving = false; - if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING, - "startActivity() behind front, mUserLeaving=false"); - } - - task = activityTask; - // Slot the activity into the history root task and proceed - ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s " - + "callers: %s", r, task, new RuntimeException("here").fillInStackTrace()); + ProtoLog.i(WM_DEBUG_ADD_REMOVE, "Adding activity %s to task %s callers: %s", r, + activityTask, new RuntimeException("here").fillInStackTrace()); if (isActivityTypeHomeOrRecents() && getActivityBelow(r) == null) { // If this is the first activity, don't do any fancy animations, @@ -5364,15 +5335,15 @@ class Task extends TaskFragment { return; } - final DisplayContent dc = mDisplayContent; - if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, - "Prepare open transition: starting " + r); + if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: starting " + r); + + // Place a new activity at top of root task, so it is next to interact with the user. if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - dc.prepareAppTransition(TRANSIT_NONE); + mDisplayContent.prepareAppTransition(TRANSIT_NONE); mTaskSupervisor.mNoAnimActivities.add(r); mTransitionController.setNoAnimation(r); } else { - dc.prepareAppTransition(TRANSIT_OPEN); + mDisplayContent.prepareAppTransition(TRANSIT_OPEN); mTaskSupervisor.mNoAnimActivities.remove(r); } if (newTask && !r.mLaunchTaskBehind) { @@ -5423,8 +5394,7 @@ class Task extends TaskFragment { // "has the same starting icon" as the next one. This allows the // window manager to keep the previous window it had previously // created, if it still had one. - Task baseTask = r.getTask(); - final ActivityRecord prev = baseTask.getActivity( + final ActivityRecord prev = activityTask.getActivity( a -> a.mStartingData != null && a.showToCurrentUser()); mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask, isTaskSwitch, sourceRecord); diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index a031acad638f..1993053c16cd 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -409,6 +409,9 @@ class TaskFragment extends WindowContainer<WindowContainer> { private boolean mForceTranslucent = false; + /** @see #setCanAffectSystemUiFlags */ + private boolean mCanAffectSystemUiFlags = true; + final Point mLastSurfaceSize = new Point(); private final Rect mTmpBounds = new Rect(); @@ -967,6 +970,27 @@ class TaskFragment extends WindowContainer<WindowContainer> { } /** + * @param canAffectSystemUiFlags If false, all windows in this taskfragment can not affect + * SystemUI flags. See + * {@link WindowState#canAffectSystemUiFlags()}. + */ + void setCanAffectSystemUiFlags(boolean canAffectSystemUiFlags) { + mCanAffectSystemUiFlags = canAffectSystemUiFlags; + } + + /** + * @see #setCanAffectSystemUiFlags + */ + boolean canAffectSystemUiFlags() { + if (!mCanAffectSystemUiFlags) { + return false; + } + final TaskFragment parentTaskFragment = + getParent() != null ? getParent().asTaskFragment() : null; + return parentTaskFragment == null || parentTaskFragment.canAffectSystemUiFlags(); + } + + /** * Returns the TaskFragment that is being organized, which could be this or the ascendant * TaskFragment. */ diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index f4a455a9c2dd..75cefdff2b0b 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -2890,6 +2890,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { leashReference = leashReference.getParent(); } } + if (wc == leashReference + && sortedTargets.get(i).mWindowingMode == WINDOWING_MODE_PINNED) { + // If a PiP task is the only target, we wanna make sure the transition root leash + // is at the top in case PiP is sent to back. This is done because a pinned task is + // meant to be always-on-top throughout a transition. + leashReference = ancestor.getTopChild(); + } final SurfaceControl rootLeash = leashReference.makeAnimationLeash().setName( "Transition Root: " + leashReference.getName()) .setCallsite("Transition.calculateTransitionRoots").build(); diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java index 9780d3317e11..eb6eeb31e8fb 100644 --- a/services/core/java/com/android/server/wm/Watermark.java +++ b/services/core/java/com/android/server/wm/Watermark.java @@ -126,8 +126,9 @@ class Watermark { } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; - mBlastBufferQueue = new BLASTBufferQueue(TITLE, mSurfaceControl, 1 /* width */, - 1 /* height */, PixelFormat.RGBA_8888); + mBlastBufferQueue = new BLASTBufferQueue(TITLE, /* updateDestinationFrame */ true); + mBlastBufferQueue.update(mSurfaceControl, 1 /* width */, 1 /* height */, + PixelFormat.RGBA_8888); mSurface = mBlastBufferQueue.createSurface(); } diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java index 7ef8d8d0c16a..df70ed2e99a8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerFlags.java +++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java @@ -58,6 +58,8 @@ class WindowManagerFlags { final boolean mEnsureWallpaperInTransitions; + final boolean mAodTransition = Flags.aodTransition(); + /* End Available Flags */ WindowManagerFlags() { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index bf23e757fee5..1754d7346220 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -513,7 +513,6 @@ public class WindowManagerService extends IWindowManager.Stub public void onVrStateChanged(boolean enabled) { synchronized (mGlobalLock) { mVrModeEnabled = enabled; - mRoot.forAllDisplayPolicies(p -> p.onVrStateChangedLw(enabled)); } } }; @@ -754,8 +753,6 @@ public class WindowManagerService extends IWindowManager.Stub final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2; int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE; - /** Indicates that the system server is actively demanding the screen be frozen. */ - boolean mClientFreezingScreen = false; int mAppsFreezingScreen = 0; @VisibleForTesting @@ -881,11 +878,6 @@ public class WindowManagerService extends IWindowManager.Stub return; } - if (mImmersiveModeConfirmationsUri.equals(uri) || mPolicyControlUri.equals(uri)) { - updateSystemUiSettings(true /* handleChange */); - return; - } - if (mForceDesktopModeOnExternalDisplaysUri.equals(uri)) { updateForceDesktopModeOnExternalDisplays(); return; @@ -938,7 +930,6 @@ public class WindowManagerService extends IWindowManager.Stub } void loadSettings() { - updateSystemUiSettings(false /* handleChange */); updateMaximumObscuringOpacityForTouch(); updateDisableSecureWindows(); } @@ -955,21 +946,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - void updateSystemUiSettings(boolean handleChange) { - synchronized (mGlobalLock) { - boolean changed = false; - if (handleChange) { - changed = getDefaultDisplayContentLocked().getDisplayPolicy() - .onSystemUiSettingsChanged(); - } else { - ImmersiveModeConfirmation.loadSetting(mCurrentUserId, mContext); - } - if (changed) { - mWindowPlacerLocked.requestTraversal(); - } - } - } - void updateForceDesktopModeOnExternalDisplays() { ContentResolver resolver = mContext.getContentResolver(); final boolean enableForceDesktopMode = Settings.Global.getInt(resolver, @@ -3315,7 +3291,6 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void onUserSwitched() { - mSettingsObserver.updateSystemUiSettings(true /* handleChange */); synchronized (mGlobalLock) { // force a re-application of focused window sysui visibility on each display. mRoot.forAllDisplayPolicies(DisplayPolicy::resetSystemBarAttributes); @@ -3377,60 +3352,6 @@ public class WindowManagerService extends IWindowManager.Stub return getDefaultDisplayContentLocked().mAppTransition.isIdle(); } - - // ------------------------------------------------------------- - // Misc IWindowSession methods - // ------------------------------------------------------------- - - /** Freeze the screen during a user-switch event. Called by UserController. */ - @Override - public void startFreezingScreen(int exitAnim, int enterAnim) { - if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, - "startFreezingScreen()")) { - throw new SecurityException("Requires FREEZE_SCREEN permission"); - } - - synchronized (mGlobalLock) { - if (!mClientFreezingScreen) { - mClientFreezingScreen = true; - final long origId = Binder.clearCallingIdentity(); - try { - startFreezingDisplay(exitAnim, enterAnim); - mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); - mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - } - - /** - * No longer actively demand that the screen remain frozen. - * Called by UserController after a user-switch. - * This doesn't necessarily immediately unlock the screen; it just allows it if we're ready. - */ - @Override - public void stopFreezingScreen() { - if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, - "stopFreezingScreen()")) { - throw new SecurityException("Requires FREEZE_SCREEN permission"); - } - - synchronized (mGlobalLock) { - if (mClientFreezingScreen) { - mClientFreezingScreen = false; - mLastFinishedFreezeSource = "client"; - final long origId = Binder.clearCallingIdentity(); - try { - stopFreezingDisplayLocked(); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - } - @Override public void disableKeyguard(IBinder token, String tag, int userId) { userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), @@ -5692,7 +5613,6 @@ public class WindowManagerService extends IWindowManager.Stub public static final int WAITING_FOR_DRAWN_TIMEOUT = 24; public static final int SHOW_STRICT_MODE_VIOLATION = 25; - public static final int CLIENT_FREEZE_TIMEOUT = 30; public static final int NOTIFY_ACTIVITY_DRAWN = 32; public static final int NEW_ANIMATOR_SCALE = 34; @@ -5782,17 +5702,6 @@ public class WindowManagerService extends IWindowManager.Stub break; } - case CLIENT_FREEZE_TIMEOUT: { - synchronized (mGlobalLock) { - if (mClientFreezingScreen) { - mClientFreezingScreen = false; - mLastFinishedFreezeSource = "client-timeout"; - stopFreezingDisplayLocked(); - } - } - break; - } - case REPORT_WINDOWS_CHANGE: { if (mWindowsChanged) { synchronized (mGlobalLock) { @@ -6575,14 +6484,14 @@ public class WindowManagerService extends IWindowManager.Stub } if (waitingForConfig || waitingForRemoteDisplayChange || mAppsFreezingScreen > 0 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE - || mClientFreezingScreen || numOpeningApps > 0) { + || numOpeningApps > 0) { ProtoLog.d(WM_DEBUG_ORIENTATION, "stopFreezingDisplayLocked: Returning " + "waitingForConfig=%b, waitingForRemoteDisplayChange=%b, " + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, " - + "mClientFreezingScreen=%b, mOpeningApps.size()=%d", + + "mOpeningApps.size()=%d", waitingForConfig, waitingForRemoteDisplayChange, mAppsFreezingScreen, mWindowsFreezingScreen, - mClientFreezingScreen, numOpeningApps); + numOpeningApps); return; } @@ -6612,7 +6521,6 @@ public class WindowManagerService extends IWindowManager.Stub } ProtoLog.i(WM_ERROR, "%s", sb.toString()); mH.removeMessages(H.APP_FREEZE_TIMEOUT); - mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); if (PROFILE_ORIENTATION) { Debug.stopMethodTracing(); } @@ -7119,7 +7027,6 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mTransactionSequence="); pw.println(mTransactionSequence); pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen); pw.print(" windows="); pw.print(mWindowsFreezingScreen); - pw.print(" client="); pw.print(mClientFreezingScreen); pw.print(" apps="); pw.println(mAppsFreezingScreen); final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked(); pw.print(" mRotation="); pw.println(defaultDisplayContent.getRotation()); @@ -9071,22 +8978,6 @@ public class WindowManagerService extends IWindowManager.Stub return mSurfaceControlFactory.get(); } - /** - * Called when the state of lock task mode changes. This should be used to disable immersive - * mode confirmation. - * - * @param lockTaskState the new lock task mode state. One of - * {@link ActivityManager#LOCK_TASK_MODE_NONE}, - * {@link ActivityManager#LOCK_TASK_MODE_LOCKED}, - * {@link ActivityManager#LOCK_TASK_MODE_PINNED}. - */ - void onLockTaskStateChanged(int lockTaskState) { - // TODO: pass in displayId to determine which display the lock task state changed - synchronized (mGlobalLock) { - mRoot.forAllDisplayPolicies(p -> p.onLockTaskStateChangedLw(lockTaskState)); - } - } - @Override public void syncInputTransactions(boolean waitForAnimations) { final long token = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index f0f1b2e47cc8..3c3a180f4da1 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -38,6 +38,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_ import static android.window.TaskFragmentOperation.OP_TYPE_REQUEST_FOCUS_ON_TASK_FRAGMENT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; +import static android.window.TaskFragmentOperation.OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_DECOR_SURFACE_BOOSTED; import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK; @@ -1862,6 +1863,13 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub taskFragment.setPinned(pinned); break; } + case OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS: { + taskFragment.setCanAffectSystemUiFlags(operation.getBooleanValue()); + + // Request to apply the flags. + mService.mWindowManager.mWindowPlacerLocked.requestTraversal(); + break; + } } return effects; } @@ -1937,6 +1945,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return false; } + if ((opType == OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS) + && !mTaskFragmentOrganizerController.isSystemOrganizer(organizer.asBinder())) { + final Throwable exception = new SecurityException( + "Only a system organizer can perform OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS." + ); + sendTaskFragmentOperationFailure(organizer, errorCallbackToken, taskFragment, + opType, exception); + return false; + } + final IBinder secondaryFragmentToken = operation.getSecondaryFragmentToken(); return secondaryFragmentToken == null || validateTaskFragment(mLaunchTaskFragments.get(secondaryFragmentToken), opType, diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java index c0bc8e094a39..2aa0c6b6dd0b 100644 --- a/services/credentials/java/com/android/server/credentials/RequestSession.java +++ b/services/credentials/java/com/android/server/credentials/RequestSession.java @@ -258,12 +258,33 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential if (propagateCancellation) { mProviders.values().forEach(ProviderSession::cancelProviderRemoteSession); } - mRequestSessionMetric.logApiCalledAtFinish(apiStatus); mRequestSessionStatus = RequestSessionStatus.COMPLETE; + if (Flags.fixMetricDuplicationEmits()) { + logTrackOneCandidatesAndPrepareFinalPhaseLogs(apiStatus); + } + mRequestSessionMetric.logApiCalledAtFinish(apiStatus); mProviders.clear(); clearRequestSessionLocked(); } + /** + * Ensures all logging done in final phase methods only occur within the 'finishSession'. + */ + private void logTrackOneCandidatesAndPrepareFinalPhaseLogs(int apiStatus) { + mRequestSessionMetric.logCandidateAggregateMetrics(mProviders); + if (isRespondingWithError(apiStatus)) { + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( + /*hasException=*/ true, ProviderStatusForMetrics.FINAL_FAILURE); + } else if (isRespondingWithUserCanceledError(apiStatus)) { + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( + /*hasException=*/false, ProviderStatusForMetrics.FINAL_FAILURE + ); + } else if (isRespondingWithSuccess(apiStatus)) { + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus(/*hasException=*/ false, + ProviderStatusForMetrics.FINAL_SUCCESS); + } + } + void cancelExistingPendingIntent() { if (mPendingIntent != null) { try { @@ -343,9 +364,11 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential * @param response the response associated with the API call that just completed */ protected void respondToClientWithResponseAndFinish(V response) { - mRequestSessionMetric.logCandidateAggregateMetrics(mProviders); - mRequestSessionMetric.collectFinalPhaseProviderMetricStatus(/*has_exception=*/ false, - ProviderStatusForMetrics.FINAL_SUCCESS); + if (!Flags.fixMetricDuplicationEmits()) { + mRequestSessionMetric.logCandidateAggregateMetrics(mProviders); + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus(/*hasException=*/ false, + ProviderStatusForMetrics.FINAL_SUCCESS); + } if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Slog.w(TAG, "Request has already been completed. This is strange."); return; @@ -360,8 +383,10 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential finishSession(/*propagateCancellation=*/false, ApiStatus.SUCCESS.getMetricCode()); } catch (RemoteException e) { - mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( - /*has_exception=*/ true, ProviderStatusForMetrics.FINAL_FAILURE); + if (!Flags.fixMetricDuplicationEmits()) { + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( + /*hasException=*/ true, ProviderStatusForMetrics.FINAL_FAILURE); + } Slog.e(TAG, "Issue while responding to client with a response : " + e); finishSession(/*propagateCancellation=*/false, ApiStatus.FAILURE.getMetricCode()); } @@ -374,9 +399,11 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential * @param errorMsg the error message given back in the flow */ protected void respondToClientWithErrorAndFinish(String errorType, String errorMsg) { - mRequestSessionMetric.logCandidateAggregateMetrics(mProviders); - mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( - /*has_exception=*/ true, ProviderStatusForMetrics.FINAL_FAILURE); + if (!Flags.fixMetricDuplicationEmits()) { + mRequestSessionMetric.logCandidateAggregateMetrics(mProviders); + mRequestSessionMetric.collectFinalPhaseProviderMetricStatus( + /*hasException=*/ true, ProviderStatusForMetrics.FINAL_FAILURE); + } if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) { Slog.w(TAG, "Request has already been completed. This is strange."); return; @@ -385,7 +412,6 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential finishSession(/*propagateCancellation=*/true, ApiStatus.CLIENT_CANCELED.getMetricCode()); return; } - try { invokeClientCallbackError(errorType, errorMsg); } catch (RemoteException e) { @@ -393,7 +419,9 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential } boolean isUserCanceled = errorType.contains(MetricUtilities.USER_CANCELED_SUBSTRING); if (isUserCanceled) { - mRequestSessionMetric.setHasExceptionFinalPhase(/* has_exception */ false); + if (!Flags.fixMetricDuplicationEmits()) { + mRequestSessionMetric.setHasExceptionFinalPhase(/* hasException */ false); + } finishSession(/*propagateCancellation=*/false, ApiStatus.USER_CANCELED.getMetricCode()); } else { @@ -421,4 +449,26 @@ abstract class RequestSession<T, U, V> implements CredentialManagerUi.Credential finishSession(isUiWaitingForData(), ApiStatus.CLIENT_CANCELED.getMetricCode()); } } + + /** + * This captures the final state of the apiStatus as presented in 'finishSession'. + */ + private boolean isRespondingWithError(int apiStatus) { + return apiStatus == ApiStatus.FAILURE.getMetricCode() + || apiStatus == ApiStatus.CLIENT_CANCELED.getMetricCode(); + } + + /** + * A unique failure case, where we do not set the exception bit to be true. + */ + private boolean isRespondingWithUserCanceledError(int apiStatus) { + return apiStatus == ApiStatus.USER_CANCELED.getMetricCode(); + } + + /** + * This captures the final state of the apiStatus as presented in 'finishSession'. + */ + private boolean isRespondingWithSuccess(int apiStatus) { + return apiStatus == ApiStatus.SUCCESS.getMetricCode(); + } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index fadab1f8832e..25e9f8a38f89 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1527,6 +1527,8 @@ public final class SystemServer implements Dumpable { boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice", false); + boolean isDesktop = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PC); + boolean isWatch = RoSystemFeatures.hasFeatureWatch(context); boolean isArc = context.getPackageManager().hasSystemFeature( @@ -1656,7 +1658,7 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } - if (!isTv) { + if (!isTv && !isDesktop) { t.traceBegin("StartVibratorManagerService"); mSystemServiceManager.startService(VibratorManagerService.Lifecycle.class); t.traceEnd(); diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java index f5bed999d5a0..5393e20889c0 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java @@ -455,8 +455,9 @@ public class LocalDisplayAdapterTest { * Confirm that external display uses physical density. */ @Test - public void testDpiValues() throws Exception { + public void testDpiValues_baseDensityForExternalDisplaysDisabled() throws Exception { // needs default one always + doReturn(false).when(mFlags).isBaseDensityForExternalDisplaysEnabled(); setUpDisplay(new FakeDisplay(PORT_A)); setUpDisplay(new FakeDisplay(PORT_B)); updateAvailableDisplays(); @@ -472,6 +473,25 @@ public class LocalDisplayAdapterTest { 16000); } + @Test + public void testDpiValues_baseDensityForExternalDisplaysEnabled() throws Exception { + // needs default one always + doReturn(true).when(mFlags).isBaseDensityForExternalDisplaysEnabled(); + setUpDisplay(new FakeDisplay(PORT_A)); + setUpDisplay(new FakeDisplay(PORT_B)); + updateAvailableDisplays(); + mAdapter.registerLocked(); + + waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS); + + assertDisplayDpi( + mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(), PORT_A, 100, 100, + 100); + assertDisplayDpi( + mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(), PORT_B, 100, 100, + 100); + } + private static class DisplayModeWrapper { public SurfaceControl.DisplayMode mode; public float[] expectedAlternativeRefreshRates; diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java index d9256247b835..6b138b986fe7 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java @@ -27,6 +27,7 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING; import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; +import static android.service.dreams.Flags.FLAG_ALLOW_DREAM_WHEN_POSTURED; import static com.android.server.deviceidle.Flags.FLAG_DISABLE_WAKELOCKS_IN_LIGHT_IDLE; @@ -81,8 +82,8 @@ import android.os.BatterySaverPolicyConfig; import android.os.Binder; import android.os.Handler; import android.os.IBinder; -import android.os.IWakeLockCallback; import android.os.IScreenTimeoutPolicyListener; +import android.os.IWakeLockCallback; import android.os.Looper; import android.os.PowerManager; import android.os.PowerManagerInternal; @@ -120,8 +121,8 @@ import com.android.server.power.PowerManagerService.WakeLock; import com.android.server.power.batterysaver.BatterySaverController; import com.android.server.power.batterysaver.BatterySaverPolicy; import com.android.server.power.batterysaver.BatterySaverStateMachine; -import com.android.server.power.feature.flags.Flags; import com.android.server.power.feature.PowerManagerFlags; +import com.android.server.power.feature.flags.Flags; import com.android.server.testutils.OffsettableClock; import com.google.testing.junit.testparameterinjector.TestParameter; @@ -279,6 +280,8 @@ public class PowerManagerServiceTest { Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0); Settings.Secure.putInt(mContextSpy.getContentResolver(), Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0); + Settings.Secure.putInt(mContextSpy.getContentResolver(), + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, 0); mClock = new OffsettableClock.Stopped(); mTestLooper = new TestLooper(mClock::now); @@ -1215,6 +1218,52 @@ public class PowerManagerServiceTest { assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); } + @EnableFlags(FLAG_ALLOW_DREAM_WHEN_POSTURED) + @Test + public void testDreamActivateWhilePosturedEnabled_postured_afterTimeout_goesToDreaming() { + when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true); + Settings.Secure.putInt(mContextSpy.getContentResolver(), + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, 1); + + doAnswer(inv -> { + when(mDreamManagerInternalMock.isDreaming()).thenReturn(true); + return null; + }).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString()); + + setMinimumScreenOffTimeoutConfig(5); + createService(); + startSystem(); + mService.getLocalServiceInstance().setDevicePostured(true); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + + advanceTime(15000); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING); + } + + @EnableFlags(FLAG_ALLOW_DREAM_WHEN_POSTURED) + @Test + public void testDreamActivateWhilePosturedEnabled_notPostured_afterTimeout_goesToDozing() { + when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true); + Settings.Secure.putInt(mContextSpy.getContentResolver(), + Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, 1); + + doAnswer(inv -> { + when(mDreamManagerInternalMock.isDreaming()).thenReturn(true); + return null; + }).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString()); + + setMinimumScreenOffTimeoutConfig(5); + createService(); + startSystem(); + mService.getLocalServiceInstance().setDevicePostured(false); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + + advanceTime(15000); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING); + } + @EnableFlags(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER) @SuppressWarnings("GuardedBy") @Test diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java index 9b45ca79fdab..ec8ede06099f 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java @@ -51,6 +51,7 @@ public class BatteryChargeCalculatorTest { @Before public void setup() { + mStatsRule.getBatteryStats().setNoAutoReset(true); mStatsRule.getBatteryStats().onSystemReady(mock(Context.class)); } @@ -83,8 +84,8 @@ public class BatteryChargeCalculatorTest { .isWithin(PRECISION).of(360.0); assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()) .isWithin(PRECISION).of(400.0); - // 5_000_000 (current time) - 1_000_000 (started discharging) - assertThat(batteryUsageStats.getDischargeDurationMs()).isEqualTo(4_000_000); + // 5_000_000 (current time) - 0 (started discharging, see BatteryUsageStatsRule) + assertThat(batteryUsageStats.getDischargeDurationMs()).isEqualTo(5_000_000); assertThat(batteryUsageStats.getBatteryTimeRemainingMs()).isEqualTo(8_000_000); assertThat(batteryUsageStats.getChargeTimeRemainingMs()).isEqualTo(-1); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java index d83dc110800a..db3268729f1e 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java @@ -141,8 +141,7 @@ public class BatteryStatsImplTest { HandlerThread bgThread = new HandlerThread("bg thread"); bgThread.start(); mHandler = new Handler(bgThread.getLooper()); - mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock, null, mHandler) - .setPowerProfile(mPowerProfile) + mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock, null, mHandler, mPowerProfile) .setCpuScalingPolicies(mCpuScalingPolicies) .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader) .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader) @@ -919,11 +918,11 @@ public class BatteryStatsImplTest { synchronized (mBatteryStatsImpl) { mBatteryStatsImpl.setOnBatteryLocked(mMockClock.realtime, mMockClock.uptime, true, BatteryManager.BATTERY_STATUS_DISCHARGING, 50, 0); - // Will not save to PowerStatsStore because "saveBatteryUsageStatsOnReset" has not - // been called yet. - mBatteryStatsImpl.resetAllStatsAndHistoryLocked( - BatteryStatsImpl.RESET_REASON_ADB_COMMAND); } + // Will not save to PowerStatsStore because "saveBatteryUsageStatsOnReset" has not + // been called yet. + mBatteryStatsImpl.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + awaitCompletion(); assertThat(mPowerStatsStore.getTableOfContents()).isEmpty(); @@ -945,15 +944,8 @@ public class BatteryStatsImplTest { mMockClock.currentTime += 60000; // Battery stats reset should have the side-effect of saving accumulated battery usage stats - synchronized (mBatteryStatsImpl) { - mBatteryStatsImpl.resetAllStatsAndHistoryLocked( - BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } - - // Await completion - ConditionVariable done = new ConditionVariable(); - mHandler.post(done::open); - done.block(); + mBatteryStatsImpl.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + awaitCompletion(); List<PowerStatsSpan.Metadata> contents = mPowerStatsStore.getTableOfContents(); assertThat(contents).hasSize(1); @@ -982,4 +974,11 @@ public class BatteryStatsImplTest { span.close(); } + + private void awaitCompletion() { + // Await completion + ConditionVariable done = new ConditionVariable(); + mHandler.post(done::open); + done.block(); + } } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java index 69579d6cb7d8..30ff8005563a 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java @@ -32,7 +32,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; import android.app.ActivityManager; import android.app.usage.NetworkStatsManager; @@ -67,7 +66,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.os.BatteryStatsHistoryIterator; import com.android.internal.os.MonotonicClock; -import com.android.internal.os.PowerProfile; import com.android.internal.power.EnergyConsumerStats; import com.android.server.power.optimization.Flags; import com.android.server.power.stats.BatteryStatsImpl.DualTimer; @@ -1538,7 +1536,6 @@ public class BatteryStatsNoteTest { public void testGetPerStateActiveRadioDurationMs_initialModemActivity() { final MockClock clock = new MockClock(); // holds realtime and uptime in ms final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); - bi.setPowerProfile(mock(PowerProfile.class)); final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; @@ -1680,7 +1677,6 @@ public class BatteryStatsNoteTest { public void testGetPerStateActiveRadioDurationMs_withModemActivity() { final MockClock clock = new MockClock(); // holds realtime and uptime in ms final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); - bi.setPowerProfile(mock(PowerProfile.class)); final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); @@ -1920,7 +1916,6 @@ public class BatteryStatsNoteTest { public void testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity() { final MockClock clock = new MockClock(); // holds realtime and uptime in ms final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); - bi.setPowerProfile(mock(PowerProfile.class)); final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); @@ -2313,7 +2308,6 @@ public class BatteryStatsNoteTest { boolean update; final MockClock clocks = new MockClock(); // holds realtime and uptime in ms final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); - bi.setPowerProfile(mock(PowerProfile.class)); final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java index 3635e9a749e2..b6d49d0ade0a 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java @@ -34,7 +34,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; -import java.nio.file.Files; @SmallTest @RunWith(AndroidJUnit4.class) @@ -45,13 +44,17 @@ public class BatteryStatsResetTest { .setProvideMainThread(true) .build(); + @Rule(order = 1) + public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule() + .createTempDirectory(); + private static final int BATTERY_NOMINAL_VOLTAGE_MV = 3700; private static final int BATTERY_CAPACITY_UAH = 4_000_000; private static final int BATTERY_CHARGE_RATE_SECONDS_PER_LEVEL = 100; private MockClock mMockClock; - private BatteryStatsImpl.BatteryStatsConfig mConfig; private MockBatteryStatsImpl mBatteryStatsImpl; + private BatteryStatsImpl.BatteryStatsConfig mConfig; /** * Battery status. Must be one of the following: @@ -92,10 +95,9 @@ public class BatteryStatsResetTest { @Before public void setUp() throws IOException { - mConfig = mock(BatteryStatsImpl.BatteryStatsConfig.class); - mMockClock = new MockClock(); - mBatteryStatsImpl = new MockBatteryStatsImpl(mConfig, mMockClock, - Files.createTempDirectory("BatteryStatsResetTest").toFile()); + mMockClock = mStatsRule.getMockClock(); + mConfig = mStatsRule.getBatteryStatsConfig(); + mBatteryStatsImpl = mStatsRule.getBatteryStats(); mBatteryStatsImpl.onSystemReady(mock(Context.class)); // Set up the battery state. Start off with a fully charged plugged in battery. @@ -112,6 +114,21 @@ public class BatteryStatsResetTest { @Test public void testResetOnUnplug_highBatteryLevel() { + mBatteryStatsImpl.resetBatteryHistoryOnNewSession(false); + long initialStartTime = mBatteryStatsImpl.getHistory().getStartTime(); + resetOnUnplug_highBatteryLevel(); + assertThat(mBatteryStatsImpl.getHistory().getStartTime()).isEqualTo(initialStartTime); + } + + @Test + public void testResetOnUnplug_highBatteryLevel_resetHistory() { + mBatteryStatsImpl.resetBatteryHistoryOnNewSession(true); + resetOnUnplug_highBatteryLevel(); + assertThat(mBatteryStatsImpl.getHistory().getStartTime()) + .isEqualTo(mBatteryStatsImpl.getMonotonicStartTime()); + } + + private void resetOnUnplug_highBatteryLevel() { when(mConfig.shouldResetOnUnplugHighBatteryLevel()).thenReturn(true); long expectedResetTimeUs = 0; @@ -149,6 +166,21 @@ public class BatteryStatsResetTest { @Test public void testResetOnUnplug_significantCharge() { + mBatteryStatsImpl.resetBatteryHistoryOnNewSession(false); + long initialStartTime = mBatteryStatsImpl.getHistory().getStartTime(); + resetOnUnplug_significantCharge(); + assertThat(mBatteryStatsImpl.getHistory().getStartTime()).isEqualTo(initialStartTime); + } + + @Test + public void testResetOnUnplug_significantCharge_resetHistory() { + mBatteryStatsImpl.resetBatteryHistoryOnNewSession(true); + resetOnUnplug_significantCharge(); + assertThat(mBatteryStatsImpl.getHistory().getStartTime()) + .isEqualTo(mBatteryStatsImpl.getMonotonicStartTime()); + } + + private void resetOnUnplug_significantCharge() { when(mConfig.shouldResetOnUnplugAfterSignificantCharge()).thenReturn(true); long expectedResetTimeUs = 0; @@ -244,7 +276,7 @@ public class BatteryStatsResetTest { } @Test - public void testResetWhilePluggedIn_longPlugIn() { + public void testResetWhilePluggedIn_longPlugIn() throws Throwable { // disable high battery level reset on unplug. when(mConfig.shouldResetOnUnplugHighBatteryLevel()).thenReturn(false); when(mConfig.shouldResetOnUnplugAfterSignificantCharge()).thenReturn(false); @@ -253,18 +285,22 @@ public class BatteryStatsResetTest { plugBattery(BatteryManager.BATTERY_PLUGGED_USB); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); - // Reset should not occur + mStatsRule.waitForBackgroundThread(); + // Reset should not have occurred assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + // Reset should still not occur assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); + // Reset 47 hour threshold crossed, reset should occur. expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000; assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); @@ -272,12 +308,14 @@ public class BatteryStatsResetTest { // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); // Reset should not occur assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); // Reset another 47 hour threshold crossed, reset should occur. expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000; assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); @@ -285,6 +323,7 @@ public class BatteryStatsResetTest { // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); // Reset should not occur assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); @@ -294,12 +333,14 @@ public class BatteryStatsResetTest { // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); // Reset should not occur, since unplug occurred recently. assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); // Increment time a day incTimeMs(24L * 60L * 60L * 1000L); mBatteryStatsImpl.maybeResetWhilePluggedInLocked(); + mStatsRule.waitForBackgroundThread(); // Reset another 47 hour threshold crossed, reset should occur. expectedResetTimeUs = mMockClock.elapsedRealtime() * 1000; assertThat(mBatteryStatsImpl.getStatsStartRealtime()).isEqualTo(expectedResetTimeUs); @@ -353,5 +394,10 @@ public class BatteryStatsResetTest { mBatteryChargeFullUah, mBatteryChargeTimeToFullSeconds, mMockClock.elapsedRealtime(), mMockClock.uptimeMillis(), mMockClock.currentTimeMillis()); + try { + mStatsRule.waitForBackgroundThread(); + } catch (Throwable e) { + throw new RuntimeException(e); + } } } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java index 73dcfe77e67f..d427c9d9ee37 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java @@ -35,7 +35,6 @@ import android.os.BatteryManager; import android.os.BatteryStats; import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; -import android.os.ConditionVariable; import android.os.Handler; import android.os.Parcel; import android.os.Process; @@ -180,6 +179,7 @@ public class BatteryUsageStatsProviderTest { private BatteryStatsImpl prepareBatteryStats(boolean plugInAtTheEnd) { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); + batteryStats.setNoAutoReset(true); batteryStats.onSystemReady(mContext); synchronized (batteryStats) { @@ -481,13 +481,12 @@ public class BatteryUsageStatsProviderTest { } @Test - public void testAggregateBatteryStats() throws IOException { + public void testAggregateBatteryStats() throws Throwable { BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats(); setTime(5 * MINUTE_IN_MS); - synchronized (batteryStats) { - batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } + batteryStats.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + mStatsRule.waitForBackgroundThread(); PowerStatsStore powerStatsStore = new PowerStatsStore( new File(mStatsRule.getHistoryDir(), "powerstatsstore"), @@ -501,9 +500,8 @@ public class BatteryUsageStatsProviderTest { batteryStats.saveBatteryUsageStatsOnReset(provider, powerStatsStore, /* accumulateBatteryUsageStats */ false); - synchronized (batteryStats) { - batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } + batteryStats.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + mStatsRule.waitForBackgroundThread(); synchronized (batteryStats) { batteryStats.noteFlashlightOnLocked(APP_UID, @@ -514,9 +512,8 @@ public class BatteryUsageStatsProviderTest { 20 * MINUTE_IN_MS, 20 * MINUTE_IN_MS); } setTime(25 * MINUTE_IN_MS); - synchronized (batteryStats) { - batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } + batteryStats.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + mStatsRule.waitForBackgroundThread(); synchronized (batteryStats) { batteryStats.noteFlashlightOnLocked(APP_UID, @@ -527,9 +524,8 @@ public class BatteryUsageStatsProviderTest { 50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS); } setTime(55 * MINUTE_IN_MS); - synchronized (batteryStats) { - batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } + batteryStats.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + mStatsRule.waitForBackgroundThread(); // This section should be ignored because the timestamp is out or range synchronized (batteryStats) { @@ -541,9 +537,8 @@ public class BatteryUsageStatsProviderTest { 70 * MINUTE_IN_MS, 70 * MINUTE_IN_MS); } setTime(75 * MINUTE_IN_MS); - synchronized (batteryStats) { - batteryStats.resetAllStatsAndHistoryLocked(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); - } + batteryStats.startNewSession(BatteryStatsImpl.RESET_REASON_ADB_COMMAND); + mStatsRule.waitForBackgroundThread(); // This section should be ignored because it represents the current stats session synchronized (batteryStats) { @@ -556,10 +551,7 @@ public class BatteryUsageStatsProviderTest { } setTime(95 * MINUTE_IN_MS); - // Await completion - ConditionVariable done = new ConditionVariable(); - mStatsRule.getHandler().post(done::open); - done.block(); + mStatsRule.waitForBackgroundThread(); // Include the first and the second snapshot, but not the third or current BatteryUsageStatsQuery query = new BatteryUsageStatsQuery.Builder() diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java index 9e7e0b646047..53a2522d299e 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java @@ -86,6 +86,7 @@ public class BatteryUsageStatsRule implements TestRule { private String[] mCustomPowerComponentNames; private Throwable mThrowable; private final BatteryStatsImpl.BatteryStatsConfig.Builder mBatteryStatsConfigBuilder; + private BatteryStatsImpl.BatteryStatsConfig mBatteryStatsConfig; public BatteryUsageStatsRule() { this(0); @@ -119,9 +120,8 @@ public class BatteryUsageStatsRule implements TestRule { } clearDirectory(); } - mBatteryStats = new MockBatteryStatsImpl(mBatteryStatsConfigBuilder.build(), - mMockClock, mMonotonicClock, mHistoryDir, mHandler, new PowerStatsUidResolver()); - mBatteryStats.setPowerProfile(mPowerProfile); + mBatteryStats = new MockBatteryStatsImpl(getBatteryStatsConfig(), mMockClock, + mMonotonicClock, mHistoryDir, mHandler, mPowerProfile, new PowerStatsUidResolver()); mBatteryStats.setCpuScalingPolicies(new CpuScalingPolicies(mCpusByPolicy, mFreqsByPolicy)); synchronized (mBatteryStats) { mBatteryStats.initEnergyConsumerStatsLocked(mSupportedStandardBuckets, @@ -142,6 +142,17 @@ public class BatteryUsageStatsRule implements TestRule { } } + /** + * Returns the BatteryStatsConfig, which is wrapped into a Mockito.spy, so it can be + * observed and/or mocked. + */ + public BatteryStatsImpl.BatteryStatsConfig getBatteryStatsConfig() { + if (mBatteryStatsConfig == null) { + mBatteryStatsConfig = spy(mBatteryStatsConfigBuilder.build()); + } + return mBatteryStatsConfig; + } + public MockClock getMockClock() { return mMockClock; } diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java index 8a081f8e16cc..a69e2fdb0b03 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MockBatteryStatsImpl.java @@ -65,29 +65,27 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { } MockBatteryStatsImpl(Clock clock, File historyDirectory) { - this(clock, historyDirectory, new Handler(Looper.getMainLooper())); + this(clock, historyDirectory, new Handler(Looper.getMainLooper()), mockPowerProfile()); } - MockBatteryStatsImpl(Clock clock, File historyDirectory, Handler handler) { - this(DEFAULT_CONFIG, clock, historyDirectory, handler, new PowerStatsUidResolver()); + MockBatteryStatsImpl(Clock clock, File historyDirectory, Handler handler, + PowerProfile powerProfile) { + this(DEFAULT_CONFIG, clock, new MonotonicClock(0, clock), historyDirectory, handler, + powerProfile, new PowerStatsUidResolver()); } - MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, File historyDirectory) { - this(config, clock, historyDirectory, new Handler(Looper.getMainLooper()), - new PowerStatsUidResolver()); - } - - MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, - File historyDirectory, Handler handler, PowerStatsUidResolver powerStatsUidResolver) { + MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, File historyDirectory, + Handler handler, PowerStatsUidResolver powerStatsUidResolver) { this(config, clock, new MonotonicClock(0, clock), historyDirectory, handler, - powerStatsUidResolver); + mockPowerProfile(), powerStatsUidResolver); } MockBatteryStatsImpl(BatteryStatsConfig config, Clock clock, MonotonicClock monotonicClock, - File historyDirectory, Handler handler, PowerStatsUidResolver powerStatsUidResolver) { + File historyDirectory, Handler handler, PowerProfile powerProfile, + PowerStatsUidResolver powerStatsUidResolver) { super(config, clock, monotonicClock, historyDirectory, handler, mock(PlatformIdleStateCallback.class), mock(EnergyStatsRetriever.class), - mock(UserInfoProvider.class), mockPowerProfile(), + mock(UserInfoProvider.class), powerProfile, new CpuScalingPolicies(new SparseArray<>(), new SparseArray<>()), powerStatsUidResolver, mock(FrameworkStatsLogger.class), mock(BatteryStatsHistory.TraceDelegate.class), @@ -172,12 +170,6 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { return mNetworkStats; } - public MockBatteryStatsImpl setPowerProfile(PowerProfile powerProfile) { - mPowerProfile = powerProfile; - setTestCpuScalingPolicies(); - return this; - } - public MockBatteryStatsImpl setTestCpuScalingPolicies() { SparseArray<int[]> cpusByPolicy = new SparseArray<>(); cpusByPolicy.put(0, new int[]{0}); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java deleted file mode 100644 index 438f0ec36177..000000000000 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/UserPowerCalculatorTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.power.stats; - -import static com.google.common.truth.Truth.assertThat; - -import android.os.BatteryConsumer; -import android.os.BatteryStats; -import android.os.BatteryUsageStatsQuery; -import android.os.Process; -import android.os.UidBatteryConsumer; -import android.os.UserBatteryConsumer; -import android.os.UserHandle; -import android.platform.test.ravenwood.RavenwoodRule; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class UserPowerCalculatorTest { - @Rule(order = 0) - public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder() - .setProvideMainThread(true) - .build(); - - public static final int USER1 = 0; - public static final int USER2 = 1625; - - private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42; - private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 272; - private static final int APP_UID3 = Process.FIRST_APPLICATION_UID + 314; - - @Rule(order = 1) - public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(); - - @Test - public void testAllUsers() { - prepareUidBatteryConsumers(); - - UserPowerCalculator calculator = new UserPowerCalculator(); - - mStatsRule.apply(BatteryUsageStatsQuery.DEFAULT, calculator, new FakeAudioPowerCalculator(), - new FakeVideoPowerCalculator()); - - assertThat(mStatsRule.getUserBatteryConsumer(USER1)).isNull(); - - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID1)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)).isEqualTo(3000); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID1)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)).isEqualTo(7000); - - assertThat(mStatsRule.getUserBatteryConsumer(USER2)).isNull(); - - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER2, APP_UID2)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)).isEqualTo(5555); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER2, APP_UID2)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)).isEqualTo(9999); - } - - @Test - public void testSpecificUser() { - prepareUidBatteryConsumers(); - - UserPowerCalculator calculator = new UserPowerCalculator(); - - mStatsRule.apply(new BatteryUsageStatsQuery.Builder().addUser(UserHandle.of(USER1)).build(), - calculator, new FakeAudioPowerCalculator(), new FakeVideoPowerCalculator()); - - assertThat(mStatsRule.getUserBatteryConsumer(USER1)).isNull(); - - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID1)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)).isEqualTo(3000); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID1)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)).isEqualTo(7000); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID2))).isNull(); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID3)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)).isEqualTo(7070); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER1, APP_UID3)) - .getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)).isEqualTo(11110); - - UserBatteryConsumer user2 = mStatsRule.getUserBatteryConsumer(USER2); - assertThat(user2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO)) - .isEqualTo(15308); - assertThat(user2.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO)) - .isEqualTo(24196); - - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER2, APP_UID1))).isNull(); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER2, APP_UID2))).isNull(); - assertThat(mStatsRule.getUidBatteryConsumer(UserHandle.getUid(USER2, APP_UID3))).isNull(); - } - - private void prepareUidBatteryConsumers() { - prepareUidBatteryConsumer(USER1, APP_UID1, 1000, 2000, 3000, 4000); - prepareUidBatteryConsumer(USER2, APP_UID2, 2222, 3333, 4444, 5555); - prepareUidBatteryConsumer(USER1, APP_UID3, 3030, 4040, 5050, 6060); - prepareUidBatteryConsumer(USER2, APP_UID3, 4321, 5432, 6543, 7654); - } - - private void prepareUidBatteryConsumer(int userId, int uid, long audioDuration1Ms, - long audioDuration2Ms, long videoDuration1Ms, long videoDuration2Ms) { - BatteryStatsImpl.Uid uidStats = mStatsRule.getUidStats(UserHandle.getUid(userId, uid)); - - // Use "audio" and "video" to fake some power consumption. Could be any other type of usage. - uidStats.noteAudioTurnedOnLocked(0); - uidStats.noteAudioTurnedOffLocked(audioDuration1Ms); - uidStats.noteAudioTurnedOnLocked(1000000); - uidStats.noteAudioTurnedOffLocked(1000000 + audioDuration2Ms); - - uidStats.noteVideoTurnedOnLocked(0); - uidStats.noteVideoTurnedOffLocked(videoDuration1Ms); - uidStats.noteVideoTurnedOnLocked(2000000); - uidStats.noteVideoTurnedOffLocked(2000000 + videoDuration2Ms); - } - - private static class FakeAudioPowerCalculator extends PowerCalculator { - - @Override - public boolean isPowerComponentSupported( - @BatteryConsumer.PowerComponent int powerComponent) { - return powerComponent == BatteryConsumer.POWER_COMPONENT_AUDIO; - } - - @Override - protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, - long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { - long durationMs = u.getAudioTurnedOnTimer().getTotalTimeLocked(rawRealtimeUs, 0); - app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AUDIO, durationMs / 1000); - } - } - - private static class FakeVideoPowerCalculator extends PowerCalculator { - - @Override - public boolean isPowerComponentSupported( - @BatteryConsumer.PowerComponent int powerComponent) { - return powerComponent == BatteryConsumer.POWER_COMPONENT_VIDEO; - } - - @Override - protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, - long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) { - long durationMs = u.getVideoTurnedOnTimer().getTotalTimeLocked(rawRealtimeUs, 0); - app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_VIDEO, durationMs / 1000); - } - } -} diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java index ed927c6ab699..d8059a6e1d2a 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerStatsCollectorTest.java @@ -80,6 +80,7 @@ public class WakelockPowerStatsCollectorTest { POWER_COMPONENT_WAKELOCK); mBatteryStats.forceRecordAllHistory(); + mBatteryStats.setNoAutoReset(true); mStatsRule.advanceSuspendedTime(1000); diff --git a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java index cc5be7ebba62..1522954c123f 100644 --- a/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/BinaryTransparencyServiceTest.java @@ -46,17 +46,14 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemProperties; import android.provider.DeviceConfig; -import android.util.Log; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.android.internal.util.FrameworkStatsLog; import com.android.internal.os.IBinaryTransparencyService; -import com.android.server.pm.BackgroundInstallControlService; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.pm.BackgroundInstallControlCallbackHelper; -import com.android.server.pm.pkg.AndroidPackage; -import com.android.server.pm.pkg.AndroidPackageSplit; +import com.android.server.pm.BackgroundInstallControlService; import com.android.server.pm.pkg.PackageStateInternal; import org.junit.After; @@ -82,7 +79,7 @@ public class BinaryTransparencyServiceTest { private Context mContext; private BinaryTransparencyService mBinaryTransparencyService; private BinaryTransparencyService.BinaryTransparencyServiceImpl mTestInterface; - private DeviceConfig.Properties mOriginalBiometricsFlags; + private String mOriginalBiometricsFlag; @Mock private BinaryTransparencyService.BiometricLogger mBiometricLogger; @@ -117,17 +114,15 @@ public class BinaryTransparencyServiceTest { mBinaryTransparencyService = new BinaryTransparencyService(mContext, mBiometricLogger); mTestInterface = mBinaryTransparencyService.new BinaryTransparencyServiceImpl(); - mOriginalBiometricsFlags = DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BIOMETRICS); + mOriginalBiometricsFlag = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_BIOMETRICS, + BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION); } @After - public void tearDown() throws Exception { - try { - DeviceConfig.setProperties(mOriginalBiometricsFlags); - } catch (DeviceConfig.BadConfigException e) { - Log.e(TAG, "Failed to reset biometrics flags to the original values before test. " - + e); - } + public void tearDown() { + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BIOMETRICS, + BinaryTransparencyService.KEY_ENABLE_BIOMETRIC_PROPERTY_VERIFICATION, + mOriginalBiometricsFlag, false /* makeDefault */); LocalServices.removeServiceForTest(PackageManagerInternal.class); } diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java index 92c6db5b7b96..5240f581fd9f 100644 --- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java @@ -166,8 +166,7 @@ public class GestureLauncherServiceTest { new GestureLauncherService( mContext, mMetricsLogger, mQuickAccessWalletClient, mUiEventLogger); - withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + Settings.Secure.clearProviderForTest(); } private WalletLaunchedReceiver registerWalletLaunchedReceiver(String action) { @@ -223,7 +222,7 @@ public class GestureLauncherServiceTest { withDoubleTapPowerModeConfigValue( DOUBLE_TAP_POWER_DISABLED_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( mContext, FAKE_USER_ID)); @@ -244,7 +243,7 @@ public class GestureLauncherServiceTest { public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configFalseSettingEnabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_DISABLED_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( mContext, FAKE_USER_ID)); @@ -265,7 +264,7 @@ public class GestureLauncherServiceTest { public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingDisabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( mContext, FAKE_USER_ID)); @@ -286,7 +285,7 @@ public class GestureLauncherServiceTest { public void testIsCameraDoubleTapPowerSettingEnabled_flagEnabled_configTrueSettingEnabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( mContext, FAKE_USER_ID)); @@ -329,7 +328,31 @@ public class GestureLauncherServiceTest { public void testIsCameraDoubleTapPowerSettingEnabled_actionWallet() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + + assertFalse( + mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( + mContext, FAKE_USER_ID)); + } + + @Test + @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testIsCameraDoubleTapPowerSettingEnabled_defaultActionCamera() { + withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); + withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + + assertTrue( + mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( + mContext, FAKE_USER_ID)); + } + + @Test + @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testIsCameraDoubleTapPowerSettingEnabled_defaultActionNotCamera() { + withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); + withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); assertFalse( mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled( @@ -341,7 +364,7 @@ public class GestureLauncherServiceTest { public void testIsWalletDoubleTapPowerSettingEnabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); assertTrue( mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( @@ -353,7 +376,7 @@ public class GestureLauncherServiceTest { public void testIsWalletDoubleTapPowerSettingEnabled_configDisabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_DISABLED_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); assertFalse( mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( @@ -365,7 +388,7 @@ public class GestureLauncherServiceTest { public void testIsWalletDoubleTapPowerSettingEnabled_settingDisabled() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(false); - withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); assertFalse( mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( @@ -377,7 +400,31 @@ public class GestureLauncherServiceTest { public void testIsWalletDoubleTapPowerSettingEnabled_actionCamera() { withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + + assertFalse( + mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( + mContext, FAKE_USER_ID)); + } + + @Test + @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testIsWalletDoubleTapPowerSettingEnabled_defaultActionWallet() { + withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); + withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + + assertTrue( + mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( + mContext, FAKE_USER_ID)); + } + + @Test + @RequiresFlagsEnabled(FLAG_LAUNCH_WALLET_OPTION_ON_POWER_DOUBLE_TAP) + public void testIsWalletDoubleTapPowerSettingEnabled_defaultActionNotWallet() { + withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); + withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); + withDefaultDoubleTapPowerGestureActionConfig(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); assertFalse( mGestureLauncherService.isWalletDoubleTapPowerSettingEnabled( @@ -1858,7 +1905,7 @@ public class GestureLauncherServiceTest { UserHandle.USER_CURRENT); } - private void withDefaultDoubleTapPowerGestureAction(int action) { + private void withDoubleTapPowerGestureActionSettingValue(int action) { Settings.Secure.putIntForUser( mContentResolver, Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE, @@ -1866,6 +1913,12 @@ public class GestureLauncherServiceTest { UserHandle.USER_CURRENT); } + private void withDefaultDoubleTapPowerGestureActionConfig(int action) { + when(mResources.getInteger( + com.android.internal.R.integer.config_doubleTapPowerGestureMultiTargetDefaultAction + )).thenReturn(action); + } + private void withEmergencyGestureEnabledConfigValue(boolean enableConfigValue) { when(mResources.getBoolean( com.android.internal.R.bool.config_emergencyGestureEnabled)) @@ -1931,7 +1984,7 @@ public class GestureLauncherServiceTest { } private void enableWalletGesture() { - withDefaultDoubleTapPowerGestureAction(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_WALLET_ON_DOUBLE_TAP_POWER); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); withDoubleTapPowerModeConfigValue(DOUBLE_TAP_POWER_MULTI_TARGET_MODE); @@ -1951,7 +2004,7 @@ public class GestureLauncherServiceTest { withDoubleTapPowerModeConfigValue( DOUBLE_TAP_POWER_MULTI_TARGET_MODE); withMultiTargetDoubleTapPowerGestureEnableSettingValue(true); - withDefaultDoubleTapPowerGestureAction(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); + withDoubleTapPowerGestureActionSettingValue(LAUNCH_CAMERA_ON_DOUBLE_TAP_POWER); } else { withCameraDoubleTapPowerEnableConfigValue(true); withCameraDoubleTapPowerDisableSettingValue(0); diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java index 464fee2bfc11..fb31cfe762f2 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java @@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static android.view.WindowManagerPolicyConstants.FLAG_PASS_TO_USER; +import static com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES; import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_AUTOCLICK; import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_CONTROL_SCREEN_MAGNIFIER; import static com.android.server.accessibility.AccessibilityInputFilter.FLAG_FEATURE_FILTER_KEY_EVENTS; @@ -39,6 +40,10 @@ import android.content.Context; import android.hardware.display.DisplayManagerGlobal; import android.os.Looper; import android.os.SystemClock; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import android.util.SparseArray; import android.view.Display; @@ -55,12 +60,14 @@ import com.android.server.LocalServices; import com.android.server.accessibility.gestures.TouchExplorer; import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler; import com.android.server.accessibility.magnification.MagnificationGestureHandler; +import com.android.server.accessibility.magnification.MagnificationKeyHandler; import com.android.server.accessibility.magnification.MagnificationProcessor; import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler; import com.android.server.wm.WindowManagerInternal; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -88,8 +95,16 @@ public class AccessibilityInputFilterTest { | FLAG_FEATURE_INJECT_MOTION_EVENTS | FLAG_FEATURE_FILTER_KEY_EVENTS; + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + // The expected order of EventStreamTransformations. private final Class[] mExpectedEventHandlerTypes = + {MagnificationKeyHandler.class, KeyboardInterceptor.class, MotionEventInjector.class, + FullScreenMagnificationGestureHandler.class, TouchExplorer.class, + AutoclickController.class, AccessibilityInputFilter.class}; + + private final Class[] mExpectedEventHandlerTypesWithoutMagKeyboard = {KeyboardInterceptor.class, MotionEventInjector.class, FullScreenMagnificationGestureHandler.class, TouchExplorer.class, AutoclickController.class, AccessibilityInputFilter.class}; @@ -176,6 +191,7 @@ public class AccessibilityInputFilterTest { } @Test + @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) public void testEventHandler_shouldIncreaseAndHaveCorrectOrderAfterOnDisplayAdded() { prepareLooper(); @@ -191,9 +207,9 @@ public class AccessibilityInputFilterTest { EventStreamTransformation next = mEventHandler.get(SECOND_DISPLAY); assertNotNull(next); - // Start from index 1 because KeyboardInterceptor only exists in EventHandler for - // DEFAULT_DISPLAY. - for (int i = 1; next != null; i++) { + // Start from index 2 because KeyboardInterceptor and MagnificationKeyHandler only exist in + // EventHandler for DEFAULT_DISPLAY. + for (int i = 2; next != null; i++) { assertEquals(next.getClass(), mExpectedEventHandlerTypes[i]); next = next.getNext(); } @@ -232,6 +248,7 @@ public class AccessibilityInputFilterTest { } @Test + @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) public void testEventHandler_shouldHaveCorrectOrderForEventStreamTransformation() { prepareLooper(); @@ -248,10 +265,36 @@ public class AccessibilityInputFilterTest { } next = mEventHandler.get(SECOND_DISPLAY); + // Start from index 2 because KeyboardInterceptor and MagnificationKeyHandler only exist + // in EventHandler for DEFAULT_DISPLAY. + for (int i = 2; next != null; i++) { + assertEquals(next.getClass(), mExpectedEventHandlerTypes[i]); + next = next.getNext(); + } + } + + @Test + @RequiresFlagsDisabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) + public void testEventHandler_shouldHaveCorrectOrderForEventStreamTransformation_noMagKeys() { + prepareLooper(); + + setDisplayCount(2); + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + assertEquals(2, mEventHandler.size()); + + // Check if mEventHandler for each display has correct order of the + // EventStreamTransformations. + EventStreamTransformation next = mEventHandler.get(DEFAULT_DISPLAY); + for (int i = 0; next != null; i++) { + assertEquals(next.getClass(), mExpectedEventHandlerTypesWithoutMagKeyboard[i]); + next = next.getNext(); + } + + next = mEventHandler.get(SECOND_DISPLAY); // Start from index 1 because KeyboardInterceptor only exists in EventHandler for // DEFAULT_DISPLAY. for (int i = 1; next != null; i++) { - assertEquals(next.getClass(), mExpectedEventHandlerTypes[i]); + assertEquals(next.getClass(), mExpectedEventHandlerTypesWithoutMagKeyboard[i]); next = next.getNext(); } } @@ -387,7 +430,6 @@ public class AccessibilityInputFilterTest { assertNotNull(handler); assertEquals(WindowMagnificationGestureHandler.class, handler.getClass()); assertEquals(nextEventStream.getClass(), handler.getNext().getClass()); - } @Test public void @@ -412,6 +454,32 @@ public class AccessibilityInputFilterTest { assertEquals(nextEventStream.getClass(), handler.getNext().getClass()); } + @Test + @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) + public void testEnabledFeatures_windowMagnificationMode_expectedMagnificationKeyHandler() { + prepareLooper(); + doReturn(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW).when( + mAms).getMagnificationMode(DEFAULT_DISPLAY); + + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + + MagnificationKeyHandler handler = getMagnificationKeyHandlerFromEventHandler(); + assertNotNull(handler); + } + + @Test + @RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) + public void testEnabledFeatures_fullscreenMagnificationMode_expectedMagnificationKeyHandler() { + prepareLooper(); + doReturn(Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN).when( + mAms).getMagnificationMode(DEFAULT_DISPLAY); + + mA11yInputFilter.setUserAndEnabledFeatures(0, mFeatures); + + MagnificationKeyHandler handler = getMagnificationKeyHandlerFromEventHandler(); + assertNotNull(handler); + } + private static void prepareLooper() { if (Looper.myLooper() == null) { Looper.prepare(); @@ -458,4 +526,16 @@ public class AccessibilityInputFilterTest { } return null; } + + @Nullable + private MagnificationKeyHandler getMagnificationKeyHandlerFromEventHandler() { + EventStreamTransformation next = mEventHandler.get(DEFAULT_DISPLAY); + while (next != null) { + if (next instanceof MagnificationKeyHandler) { + return (MagnificationKeyHandler) next; + } + next = next.getNext(); + } + return null; + } } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java index f371823473ef..1a974458403f 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java @@ -425,7 +425,6 @@ public class ProxyManagerTest { @Test public void testRegisterProxy_registersVirtualDeviceListener() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); verify(mMockIVirtualDeviceManager, times(1)).registerVirtualDeviceListener(any()); @@ -434,7 +433,6 @@ public class ProxyManagerTest { @Test public void testRegisterMultipleProxies_registersOneVirtualDeviceListener() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); registerProxy(DISPLAY_2_ID); @@ -443,7 +441,6 @@ public class ProxyManagerTest { @Test public void testUnregisterProxy_unregistersVirtualDeviceListener() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); mProxyManager.unregisterProxy(DISPLAY_ID); @@ -454,7 +451,6 @@ public class ProxyManagerTest { @Test public void testUnregisterProxy_onlyUnregistersVirtualDeviceListenerOnLastProxyRemoval() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); registerProxy(DISPLAY_2_ID); @@ -468,7 +464,6 @@ public class ProxyManagerTest { @Test public void testRegisteredProxy_virtualDeviceClosed_proxyClosed() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isTrue(); @@ -490,7 +485,6 @@ public class ProxyManagerTest { @Test public void testRegisteredProxy_unrelatedVirtualDeviceClosed_proxyNotClosed() throws RemoteException { - mSetFlagsRule.enableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); registerProxy(DISPLAY_ID); assertThat(mProxyManager.isProxyedDeviceId(DEVICE_ID)).isTrue(); @@ -507,17 +501,6 @@ public class ProxyManagerTest { assertThat(mProxyManager.isProxyedDisplay(DISPLAY_ID)).isTrue(); } - @Test - public void testRegisterProxy_doesNotRegisterVirtualDeviceListener_flagDisabled() - throws RemoteException { - mSetFlagsRule.disableFlags(android.companion.virtual.flags.Flags.FLAG_VDM_PUBLIC_APIS); - registerProxy(DISPLAY_ID); - mProxyManager.unregisterProxy(DISPLAY_ID); - - verify(mMockIVirtualDeviceManager, never()).registerVirtualDeviceListener(any()); - verify(mMockIVirtualDeviceManager, never()).unregisterVirtualDeviceListener(any()); - } - private void registerProxy(int displayId) { try { mProxyManager.registerProxy(mMockAccessibilityServiceClient, displayId, anyInt(), diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java new file mode 100644 index 000000000000..d1ef33d8fb70 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationKeyHandlerTest.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.accessibility.magnification; + +import static com.android.hardware.input.Flags.FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES; +import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_DOWN; +import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_LEFT; +import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_RIGHT; +import static com.android.server.accessibility.magnification.MagnificationController.PAN_DIRECTION_UP; +import static com.android.server.accessibility.magnification.MagnificationController.ZOOM_DIRECTION_IN; +import static com.android.server.accessibility.magnification.MagnificationController.ZOOM_DIRECTION_OUT; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.view.Display; +import android.view.KeyEvent; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.accessibility.EventStreamTransformation; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Tests for {@link MagnificationKeyHandler}. + */ +@RunWith(AndroidJUnit4.class) +@RequiresFlagsEnabled(FLAG_ENABLE_TALKBACK_AND_MAGNIFIER_KEY_GESTURES) +public class MagnificationKeyHandlerTest { + + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + + private MagnificationKeyHandler mMkh; + + @Mock + MagnificationKeyHandler.Callback mCallback; + + @Mock + EventStreamTransformation mNextHandler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mMkh = new MagnificationKeyHandler(mCallback); + mMkh.setNext(mNextHandler); + } + + @Test + public void onKeyEvent_unusedKeyPress_sendToNext() { + final KeyEvent event = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_L, 0, 0); + mMkh.onKeyEvent(event, 0); + + // No callbacks were called. + verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStop(anyInt(), anyInt()); + + // The event was passed on. + verify(mNextHandler, times(1)).onKeyEvent(event, 0); + } + + @Test + public void onKeyEvent_arrowKeyPressWithIncorrectModifiers_sendToNext() { + final KeyEvent event = + new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, + 0, KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(event, 0); + + // No callbacks were called. + verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStop(anyInt(), anyInt()); + + // The event was passed on. + verify(mNextHandler, times(1)).onKeyEvent(event, 0); + } + + @Test + public void onKeyEvent_unusedKeyPressWithCorrectModifiers_sendToNext() { + final KeyEvent event = + new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_J, 0, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(event, 0); + + // No callbacks were called. + verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStop(anyInt(), anyInt()); + + // The event was passed on. + verify(mNextHandler, times(1)).onKeyEvent(event, 0); + } + + @Test + public void onKeyEvent_panStartAndEnd_left() { + testPanMagnification(KeyEvent.KEYCODE_DPAD_LEFT, PAN_DIRECTION_LEFT); + } + + @Test + public void onKeyEvent_panStartAndEnd_right() { + testPanMagnification(KeyEvent.KEYCODE_DPAD_RIGHT, PAN_DIRECTION_RIGHT); + } + + @Test + public void onKeyEvent_panStartAndEnd_up() { + testPanMagnification(KeyEvent.KEYCODE_DPAD_UP, PAN_DIRECTION_UP); + } + + @Test + public void onKeyEvent_panStartAndEnd_down() { + testPanMagnification(KeyEvent.KEYCODE_DPAD_DOWN, PAN_DIRECTION_DOWN); + } + + @Test + public void onKeyEvent_scaleStartAndEnd_zoomIn() { + testScaleMagnification(KeyEvent.KEYCODE_EQUALS, ZOOM_DIRECTION_IN); + } + + @Test + public void onKeyEvent_scaleStartAndEnd_zoomOut() { + testScaleMagnification(KeyEvent.KEYCODE_MINUS, ZOOM_DIRECTION_OUT); + } + + @Test + public void onKeyEvent_panStartAndStop_diagonal() { + final KeyEvent downLeftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(downLeftEvent, 0); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + + // Also press the down arrow key. + final KeyEvent downDownEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(downDownEvent, 0); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_DOWN); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + + // Lift the left arrow key. + final KeyEvent upLeftEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, + KeyEvent.KEYCODE_DPAD_LEFT, 0, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(upLeftEvent, 0); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_DOWN); + verify(mCallback, times(1)).onPanMagnificationStop(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(0)).onPanMagnificationStop(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_DOWN); + + // Lift the down arrow key. + final KeyEvent upDownEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, + KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(upDownEvent, 0); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_DOWN); + verify(mCallback, times(1)).onPanMagnificationStop(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_LEFT); + verify(mCallback, times(1)).onPanMagnificationStop(Display.DEFAULT_DISPLAY, + PAN_DIRECTION_DOWN); + + // The event was not passed on. + verify(mNextHandler, times(0)).onKeyEvent(any(), anyInt()); + } + + private void testPanMagnification(int keyCode, int panDirection) { + final KeyEvent downEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, keyCode, 0, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(downEvent, 0); + + // Pan started. + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, panDirection); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + + final KeyEvent upEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode, 0, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(upEvent, 0); + + // Pan ended. + verify(mCallback, times(1)).onPanMagnificationStart(Display.DEFAULT_DISPLAY, panDirection); + verify(mCallback, times(1)).onPanMagnificationStop(Display.DEFAULT_DISPLAY, panDirection); + + // Scale callbacks were not called. + verify(mCallback, times(0)).onScaleMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onScaleMagnificationStop(anyInt(), anyInt()); + + // The events were not passed on. + verify(mNextHandler, times(0)).onKeyEvent(any(), anyInt()); + } + + private void testScaleMagnification(int keyCode, int zoomDirection) { + final KeyEvent downEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, keyCode, 0, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(downEvent, 0); + + // Scale started. + verify(mCallback, times(1)).onScaleMagnificationStart(Display.DEFAULT_DISPLAY, + zoomDirection); + verify(mCallback, times(0)).onScaleMagnificationStop(anyInt(), anyInt()); + + final KeyEvent upEvent = new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyCode, 0, + KeyEvent.META_META_ON | KeyEvent.META_ALT_ON); + mMkh.onKeyEvent(upEvent, 0); + + // Scale ended. + verify(mCallback, times(1)).onScaleMagnificationStart(Display.DEFAULT_DISPLAY, + zoomDirection); + verify(mCallback, times(1)).onScaleMagnificationStop(Display.DEFAULT_DISPLAY, + zoomDirection); + + // Pan callbacks were not called. + verify(mCallback, times(0)).onPanMagnificationStart(anyInt(), anyInt()); + verify(mCallback, times(0)).onPanMagnificationStop(anyInt(), anyInt()); + + // The events were not passed on. + verify(mNextHandler, times(0)).onKeyEvent(any(), anyInt()); + + } + +} diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java index 4d1d17f184d1..77c2447fc55f 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java @@ -31,7 +31,6 @@ import static org.mockito.Mockito.when; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.VirtualDevice; -import android.companion.virtual.flags.Flags; import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; @@ -109,8 +108,6 @@ public class VirtualDeviceTest { @Test public void virtualDevice_getDisplayIds() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); - VirtualDevice virtualDevice = new VirtualDevice( mVirtualDevice, VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null); @@ -125,8 +122,6 @@ public class VirtualDeviceTest { @Test public void virtualDevice_hasCustomSensorSupport() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); - VirtualDevice virtualDevice = new VirtualDevice( mVirtualDevice, VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null); @@ -140,7 +135,6 @@ public class VirtualDeviceTest { @Test public void virtualDevice_hasCustomAudioInputSupport() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); mSetFlagsRule.enableFlags(android.media.audiopolicy.Flags.FLAG_AUDIO_MIX_TEST_API); VirtualDevice virtualDevice = @@ -160,8 +154,6 @@ public class VirtualDeviceTest { @Test public void virtualDevice_hasCustomCameraSupport() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); - VirtualDevice virtualDevice = new VirtualDevice( mVirtualDevice, VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null); diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java index eb4a628e14e5..792faab5b196 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java @@ -25,6 +25,7 @@ import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; import static com.android.server.hdmi.Constants.ADDR_TV; import static com.android.server.hdmi.DeviceSelectActionFromTv.STATE_WAIT_FOR_DEVICE_POWER_ON; +import static com.android.server.hdmi.DeviceSelectActionFromTv.STATE_WAIT_FOR_POWER_STATE_CHANGE; import static com.android.server.hdmi.DeviceSelectActionFromTv.STATE_WAIT_FOR_REPORT_POWER_STATUS; import static com.google.common.truth.Truth.assertThat; @@ -230,11 +231,15 @@ public class DeviceSelectActionFromTvTest { "testDeviceSelect"); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); mNativeWrapper.clearResultMessages(); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_ON); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -249,10 +254,14 @@ public class DeviceSelectActionFromTvTest { /*isCec20=*/false); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_STANDBY); mTestLooper.dispatchAll(); + HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed( ADDR_TV, ADDR_PLAYBACK_1, HdmiCecKeycode.CEC_KEYCODE_POWER); assertThat(mNativeWrapper.getResultMessages()).contains(userControlPressed); @@ -261,6 +270,7 @@ public class DeviceSelectActionFromTvTest { action.handleTimerEvent(STATE_WAIT_FOR_DEVICE_POWER_ON); action.processCommand(REPORT_POWER_STATUS_ON); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -275,8 +285,11 @@ public class DeviceSelectActionFromTvTest { /*isCec20=*/false); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); mNativeWrapper.clearResultMessages(); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_STANDBY); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON); @@ -288,6 +301,7 @@ public class DeviceSelectActionFromTvTest { assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_ON); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -302,8 +316,11 @@ public class DeviceSelectActionFromTvTest { /*isCec20=*/false); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); mNativeWrapper.clearResultMessages(); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_STANDBY); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_DEVICE_POWER_ON); @@ -316,6 +333,7 @@ public class DeviceSelectActionFromTvTest { action.handleTimerEvent(STATE_WAIT_FOR_REPORT_POWER_STATUS); // Give up getting power status, and just send <Set Stream Path> mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -332,7 +350,10 @@ public class DeviceSelectActionFromTvTest { "testDeviceSelect"); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -348,11 +369,15 @@ public class DeviceSelectActionFromTvTest { "testDeviceSelect"); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); mNativeWrapper.clearResultMessages(); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_ON); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } @@ -369,10 +394,14 @@ public class DeviceSelectActionFromTvTest { /*isCec20=*/true); action.start(); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH); + assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE); + action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE); assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS); action.processCommand(REPORT_POWER_STATUS_STANDBY); mTestLooper.dispatchAll(); + HdmiCecMessage userControlPressed = HdmiCecMessageBuilder.buildUserControlPressed( ADDR_TV, ADDR_PLAYBACK_1, HdmiCecKeycode.CEC_KEYCODE_POWER); assertThat(mNativeWrapper.getResultMessages()).doesNotContain(userControlPressed); @@ -381,6 +410,7 @@ public class DeviceSelectActionFromTvTest { action.handleTimerEvent(STATE_WAIT_FOR_DEVICE_POWER_ON); action.processCommand(REPORT_POWER_STATUS_ON); mTestLooper.dispatchAll(); + assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH); assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index 1df8e3deb84b..d2f8d14c5007 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -19,13 +19,9 @@ import static android.os.UserHandle.USER_ALL; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION; import static android.service.notification.Adjustment.TYPE_NEWS; -import static android.service.notification.Adjustment.TYPE_OTHER; import static android.service.notification.Adjustment.TYPE_PROMOTION; -import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA; -import static android.service.notification.Flags.notificationClassification; import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENTS; -import static com.android.server.notification.NotificationManagerService.DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES; import static com.google.common.truth.Truth.assertThat; @@ -160,17 +156,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase { mAssistants.readXml(parser, mNm::canUseManagedServices, false, USER_ALL); } - private void setDefaultAllowedAdjustmentKeyTypes(NotificationAssistants assistants) { - assistants.setAssistantAdjustmentKeyTypeState(TYPE_OTHER, false); - assistants.setAssistantAdjustmentKeyTypeState(TYPE_PROMOTION, false); - assistants.setAssistantAdjustmentKeyTypeState(TYPE_SOCIAL_MEDIA, false); - assistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false); - assistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, false); - - for (int type : DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES) { - assistants.setAssistantAdjustmentKeyTypeState(type, true); - } - } @Before public void setUp() throws Exception { @@ -181,9 +166,6 @@ public class NotificationAssistantsTest extends UiServiceTestCase { com.android.internal.R.string.config_defaultAssistantAccessComponent, mCn.flattenToString()); mAssistants = spy(mNm.new NotificationAssistants(mContext, mLock, mUserProfiles, miPm)); - if (notificationClassification()) { - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - } when(mNm.getBinderService()).thenReturn(mINm); mContext.ensureTestableResources(); @@ -727,7 +709,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_CONTENT_RECOMMENDATION, true); assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList() - .containsExactly(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION); + .containsExactlyElementsIn(List.of(TYPE_PROMOTION, TYPE_CONTENT_RECOMMENDATION)); } @Test @@ -748,7 +730,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase { writeXmlAndReload(USER_ALL); assertThat(mAssistants.getAllowedAdjustmentKeyTypes()).asList() - .containsExactly(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION); + .containsExactlyElementsIn(List.of(TYPE_NEWS, TYPE_CONTENT_RECOMMENDATION)); } @Test @@ -765,168 +747,98 @@ public class NotificationAssistantsTest extends UiServiceTestCase { @Test @EnableFlags({android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION, android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI}) - public void testGetPackagesWithKeyTypeAdjustmentSettings() throws Exception { + public void testGetTypeAdjustmentDeniedPackages() throws Exception { String pkg = "my.package"; String pkg2 = "my.package.2"; - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); - assertThat(mAssistants.getPackagesWithKeyTypeAdjustmentSettings()).isEmpty(); + assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg)).isTrue(); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, true); - assertThat(mAssistants.getPackagesWithKeyTypeAdjustmentSettings()) + mAssistants.setTypeAdjustmentForPackageState(pkg, true); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); + mAssistants.setTypeAdjustmentForPackageState(pkg, false); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() .containsExactly(pkg); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false); - assertThat(mAssistants.getPackagesWithKeyTypeAdjustmentSettings()) + mAssistants.setTypeAdjustmentForPackageState(pkg2, true); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() .containsExactly(pkg); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg2, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg2, TYPE_PROMOTION, false); - assertThat(mAssistants.getPackagesWithKeyTypeAdjustmentSettings()) + mAssistants.setTypeAdjustmentForPackageState(pkg2, false); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() .containsExactly(pkg, pkg2); } @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void testSetAssistantAdjustmentKeyTypeStateForPackage_usesGlobalDefault() { - String pkg = "my.package"; - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactlyElementsIn(DEFAULT_ALLOWED_ADJUSTMENT_KEY_TYPES); - } - - @Test - @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsAndDenies() { - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - // Given that a package is set to have a type adjustment allowed, - String pkg = "my.package"; - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true); + public void testSetTypeAdjustmentForPackageState_allowsAndDenies() { + // Given that a package is allowed to have its type adjusted, + String allowedPackage = "allowed.package"; + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); + mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true); - // The newly set state is the combination of the global default and the newly set type. - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); + assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); // Set type adjustment disallowed for this package - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, false); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false); + mAssistants.setTypeAdjustmentForPackageState(allowedPackage, false); // Then the package is marked as denied - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).isEmpty(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isFalse(); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() + .containsExactly(allowedPackage); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); // Set type adjustment allowed again - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, true); + mAssistants.setTypeAdjustmentForPackageState(allowedPackage, true); // Then the package is marked as allowed again - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); - - // Set type adjustment promotions false, - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_PROMOTION, false); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isFalse(); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).isEmpty(); + assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPackage)); } @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void testSetAssistantAdjustmentKeyTypeStateForPackage_allowsMultiplePkgs() { - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - // Given packages allowed to have their type adjusted to TYPE_NEWS, - String allowedPkg1 = "allowed.Pkg1"; - String allowedPkg2 = "allowed.Pkg2"; - String allowedPkg3 = "allowed.Pkg3"; - // Set type adjustment allowed for these packages - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg1, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true); - - // The newly set state is the combination of the global default and the newly set type. - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue(); - - // And when we deny some of them, - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, false); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_PROMOTION, - false); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_PROMOTION, - false); - - // Then the rest of the original packages are still marked as allowed. - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg1)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).isEmpty(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() - .containsExactly(TYPE_NEWS); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg1, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg2, TYPE_NEWS)).isFalse(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(allowedPkg3, TYPE_NEWS)).isTrue(); + public void testSetAssistantAdjustmentKeyTypeStateForPackage_deniesMultiple() { + // Given packages not allowed to have their type adjusted, + String deniedPkg1 = "denied.Pkg1"; + String deniedPkg2 = "denied.Pkg2"; + String deniedPkg3 = "denied.Pkg3"; + // Set type adjustment disallowed for these packages + mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false); + mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, false); + mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false); + + // Then the packages are marked as denied + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() + .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg2, deniedPkg3)); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1)); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2)); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3)); + + // And when we re-allow one of them, + mAssistants.setTypeAdjustmentForPackageState(deniedPkg2, true); + + // Then the rest of the original packages are still marked as denied. + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() + .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3)); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg1)); + assertTrue(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg2)); + assertFalse(mAssistants.isTypeAdjustmentAllowedForPackage(deniedPkg3)); } @Test @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) public void testSetAssistantAdjustmentKeyTypeStateForPackage_readWriteXml() throws Exception { - setDefaultAllowedAdjustmentKeyTypes(mAssistants); mAssistants.loadDefaultsFromConfig(true); String deniedPkg1 = "denied.Pkg1"; String allowedPkg2 = "allowed.Pkg2"; - String allowedPkg3 = "allowed.Pkg3"; + String deniedPkg3 = "denied.Pkg3"; // Set type adjustment disallowed or allowed for these packages - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(deniedPkg1, TYPE_PROMOTION, false); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg2, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_NEWS, true); - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(allowedPkg3, TYPE_SOCIAL_MEDIA, - true); + mAssistants.setTypeAdjustmentForPackageState(deniedPkg1, false); + mAssistants.setTypeAdjustmentForPackageState(allowedPkg2, true); + mAssistants.setTypeAdjustmentForPackageState(deniedPkg3, false); writeXmlAndReload(USER_ALL); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(deniedPkg1)).isEmpty(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg2)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(allowedPkg3)).asList() - .containsExactly(TYPE_NEWS, TYPE_SOCIAL_MEDIA, TYPE_PROMOTION); - } - - @Test - @EnableFlags(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI) - public void testSetAssistantAdjustmentKeyTypeStateForPackage_noGlobalImpact() throws Exception { - setDefaultAllowedAdjustmentKeyTypes(mAssistants); - // When the global state is changed, - mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, true); - - // The package state reflects the global state. - String pkg = "my.package"; - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_PROMOTION)).isTrue(); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION); - - // Once the package specific state is modified, - mAssistants.setAssistantAdjustmentKeyTypeStateForPackage(pkg, TYPE_SOCIAL_MEDIA, true); - - // The package specific state combines the global state with those modifications - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_SOCIAL_MEDIA)).isTrue(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA); - - // And further changes to the global state are ignored. - mAssistants.setAssistantAdjustmentKeyTypeState(TYPE_NEWS, false); - assertThat(mAssistants.isTypeAdjustmentAllowedForPackage(pkg, TYPE_NEWS)).isTrue(); - assertThat(mAssistants.getAllowedAdjustmentKeyTypesForPackage(pkg)).asList() - .containsExactly(TYPE_NEWS, TYPE_PROMOTION, TYPE_SOCIAL_MEDIA); + assertThat(mAssistants.getTypeAdjustmentDeniedPackages()).asList() + .containsExactlyElementsIn(List.of(deniedPkg1, deniedPkg3)); } @Test diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index e43b28bb9404..85c592084acf 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -24,6 +24,7 @@ import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_ import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.SHOW_IMMEDIATELY; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.Flags.FLAG_KEYGUARD_PRIVATE_NOTIFICATIONS; +import static android.app.Flags.FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN; import static android.app.Flags.FLAG_SORT_SECTION_BY_TIME; import static android.app.Notification.EXTRA_ALLOW_DURING_SETUP; import static android.app.Notification.EXTRA_PICTURE; @@ -251,6 +252,9 @@ import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.session.MediaSession; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -365,9 +369,6 @@ import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import platform.test.runner.parameterized.ParameterizedAndroidJunit4; -import platform.test.runner.parameterized.Parameters; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; @@ -383,6 +384,9 @@ import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest @RunWith(ParameterizedAndroidJunit4.class) @RunWithLooper @@ -475,6 +479,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock private PowerManager mPowerManager; @Mock + private ConnectivityManager mConnectivityManager; + @Mock private LightsManager mLightsManager; private final ArrayList<WakeLock> mAcquiredWakeLocks = new ArrayList<>(); private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory = @@ -765,6 +771,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mActivityIntentImmutable = spy(PendingIntent.getActivity(mContext, 0, new Intent().setPackage(mPkg), FLAG_IMMUTABLE)); + when(mConnectivityManager.getActiveNetwork()).thenReturn(null); + initNMS(); } @@ -798,7 +806,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mAppOpsManager, mUm, mHistoryManager, mStatsManager, mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class), mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager, - mPowerManager, mPostNotificationTrackerFactory); + mPowerManager, mConnectivityManager, mPostNotificationTrackerFactory); mService.setAttentionHelper(mAttentionHelper); mService.setLockPatternUtils(mock(LockPatternUtils.class)); @@ -7654,7 +7662,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Set up notifications that will be adjusted final NotificationRecord r1 = spy(generateNotificationRecord( @@ -14314,7 +14322,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addNotification(pkgB); mService.setIsVisibleToListenerReturnValue(true); - NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(null); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); assertEquals(2, nru.getRankingMap().getOrderedKeys().length); // when only user 0 entering the lockdown mode, its notification will be suppressed. @@ -14324,7 +14333,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertTrue(mStrongAuthTracker.isInLockDownMode(0)); assertFalse(mStrongAuthTracker.isInLockDownMode(1)); - nru = mService.makeRankingUpdateLocked(null); + nru = mService.makeRankingUpdateLocked(info); assertEquals(1, nru.getRankingMap().getOrderedKeys().length); // User 0 exits lockdown mode. Its notification will be resumed. @@ -14333,7 +14342,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertFalse(mStrongAuthTracker.isInLockDownMode(0)); assertFalse(mStrongAuthTracker.isInLockDownMode(1)); - nru = mService.makeRankingUpdateLocked(null); + nru = mService.makeRankingUpdateLocked(info); assertEquals(2, nru.getRankingMap().getOrderedKeys().length); } @@ -14365,13 +14374,119 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(0, ranking2.getSmartReplies().size()); } + private NotificationRecord getSensitiveNotificationRecord() { + NotificationRecord record = new NotificationRecord(mContext, + generateSbn("a", 1000, 9, 0), mTestNotificationChannel); + Bundle signals = new Bundle(); + signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true); + Adjustment adjustment = new Adjustment("a", record.getKey(), signals, "", 0); + record.addAdjustment(adjustment); + record.applyAdjustments(); + return record; + } + + @Test + public void testMakeRankingUpdate_clearsHasSensitiveContentIfConnectedToWifi() { + mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, + FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN); + when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class)); + when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn( + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build() + ); + mService.updateWifiConnectionState(); + when(mListeners.hasSensitiveContent(any())).thenReturn(true); + NotificationRecord pkgA = new NotificationRecord(mContext, + generateSbn("a", 1000, 9, 0), mTestNotificationChannel); + mService.addNotification(pkgA); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + info.isSystemUi = true; + when(info.enabledAndUserMatches(anyInt())).thenReturn(true); + when(info.isSameUser(anyInt())).thenReturn(true); + NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); + NotificationListenerService.Ranking ranking = + nru.getRankingMap().getRawRankingObject(pkgA.getSbn().getKey()); + assertFalse(ranking.hasSensitiveContent()); + } + + @Test + public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfNotConnectedToWifi() { + mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, + FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN); + when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class)); + when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn( + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) + .build() + ); + mService.updateWifiConnectionState(); + when(mListeners.hasSensitiveContent(any())).thenReturn(true); + NotificationRecord record = getSensitiveNotificationRecord(); + mService.addNotification(record); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + info.isSystemUi = true; + when(info.enabledAndUserMatches(anyInt())).thenReturn(true); + when(info.isSameUser(anyInt())).thenReturn(true); + NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); + NotificationListenerService.Ranking ranking = + nru.getRankingMap().getRawRankingObject(record.getSbn().getKey()); + assertTrue(ranking.hasSensitiveContent()); + } + + @Test + public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfNotSysUi() { + mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); + mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN); + when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class)); + when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn( + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build() + ); + mService.updateWifiConnectionState(); + when(mListeners.hasSensitiveContent(any())).thenReturn(true); + NotificationRecord record = getSensitiveNotificationRecord(); + mService.addNotification(record); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + when(info.enabledAndUserMatches(anyInt())).thenReturn(true); + when(info.isSameUser(anyInt())).thenReturn(true); + NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); + NotificationListenerService.Ranking ranking = + nru.getRankingMap().getRawRankingObject(record.getSbn().getKey()); + assertTrue(ranking.hasSensitiveContent()); + } + + @Test + public void testMakeRankingUpdate_doesntClearHasSensitiveContentIfFlagDisabled() { + mSetFlagsRule.enableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); + mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_CONTENT_NOTIFICATIONS_ON_LOCKSCREEN); + when(mConnectivityManager.getActiveNetwork()).thenReturn(mock(Network.class)); + when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn( + new NetworkCapabilities.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build() + ); + mService.updateWifiConnectionState(); + when(mListeners.hasSensitiveContent(any())).thenReturn(true); + NotificationRecord record = getSensitiveNotificationRecord(); + mService.addNotification(record); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + info.isSystemUi = true; + when(info.enabledAndUserMatches(anyInt())).thenReturn(true); + when(info.isSameUser(anyInt())).thenReturn(true); + NotificationRankingUpdate nru = mService.makeRankingUpdateLocked(info); + NotificationListenerService.Ranking ranking = + nru.getRankingMap().getRawRankingObject(record.getSbn().getKey()); + assertTrue(ranking.hasSensitiveContent()); + } + @Test public void testMakeRankingUpdate_doestntRedactIfFlagDisabled() { mSetFlagsRule.disableFlags(FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS); when(mListeners.isUidTrusted(anyInt())).thenReturn(false); when(mListeners.hasSensitiveContent(any())).thenReturn(true); - NotificationRecord pkgA = new NotificationRecord(mContext, - generateSbn("a", 1000, 9, 0), mTestNotificationChannel); + NotificationRecord pkgA = getSensitiveNotificationRecord(); addSmartActionsAndReplies(pkgA); mService.addNotification(pkgA); @@ -17397,7 +17512,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); @@ -17441,11 +17556,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.WorkerHandler.class); mService.setHandler(handler); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_NEWS))) - .thenReturn(true); - // Blocking adjustments for a different type does nothing - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) - .thenReturn(false); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); Bundle signals = new Bundle(); signals.putInt(KEY_TYPE, TYPE_NEWS); @@ -17460,9 +17571,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID); - // When we block adjustments for this package/type - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), eq(TYPE_PROMOTION))) - .thenReturn(false); + // When we block adjustments for this package + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(false); signals.putInt(KEY_TYPE, TYPE_PROMOTION); mBinderService.applyAdjustmentFromAssistant(null, adjustment); @@ -17792,7 +17902,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; @@ -17832,7 +17942,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; @@ -17881,7 +17991,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post grouped notifications final String originalGroupName = "originalGroup"; @@ -17932,7 +18042,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true); when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true); when(mAssistants.isAdjustmentKeyTypeAllowed(anyInt())).thenReturn(true); - when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString(), anyInt())).thenReturn(true); + when(mAssistants.isTypeAdjustmentAllowedForPackage(anyString())).thenReturn(true); // Post a single notification final boolean hasOriginalSummary = false; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index c1bb3e7408fc..82d87d40031a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -47,6 +47,7 @@ import android.companion.ICompanionDeviceManager; import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.net.ConnectivityManager; import android.os.Looper; import android.os.PowerManager; import android.os.UserHandle; @@ -171,6 +172,7 @@ public class RoleObserverTest extends UiServiceTestCase { mock(NotificationChannelLogger.class), new TestableFlagResolver(), mock(PermissionManager.class), mock(PowerManager.class), + mock(ConnectivityManager.class), new NotificationManagerService.PostNotificationTrackerFactory() {}); } catch (SecurityException e) { if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 6ef078b6da8a..96fddf13cdd0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -211,7 +211,9 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.PrintWriter; import java.io.Reader; +import java.io.StringWriter; import java.time.Instant; import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; @@ -7406,6 +7408,43 @@ public class ZenModeHelperTest extends UiServiceTestCase { .isEqualTo(mZenModeHelper.getDefaultZenPolicy()); } + @Test + public void setAutomaticZenRuleState_logsOriginToZenLog() { + AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.parse("cond")) + .setPackage(mPkg) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr, + ORIGIN_APP, "adding", CUSTOM_PKG_UID); + ZenLog.clear(); + + // User enables manually from QS: + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, + new Condition(azr.getConditionId(), "", STATE_TRUE), ORIGIN_USER_IN_SYSTEMUI, + 123456); + + assertThat(getZenLog()).contains( + "config: setAzrState: " + ruleId + " (ORIGIN_USER_IN_SYSTEMUI) from uid " + 1234); + } + + @Test + public void setAutomaticZenRuleStateFromConditionProvider_logsOriginToZenLog() { + AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.parse("cond/cond")) + .setOwner(new ComponentName(CUSTOM_PKG_NAME, "SomeConditionProvider")) + .setPackage(mPkg) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr, + ORIGIN_APP, "adding", CUSTOM_PKG_UID); + ZenLog.clear(); + + // App enables rule through CPS + mZenModeHelper.setAutomaticZenRuleStateFromConditionProvider(UserHandle.CURRENT, + Uri.parse("cond/cond"), new Condition(azr.getConditionId(), "", STATE_TRUE), + ORIGIN_APP, CUSTOM_PKG_UID); + + assertThat(getZenLog()).contains( + "config: setAzrStateFromCps: cond/cond (ORIGIN_APP) from uid " + CUSTOM_PKG_UID); + } + private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode, @Nullable ZenPolicy zenPolicy) { ZenRule rule = new ZenRule(); @@ -7530,6 +7569,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(dndProto.getNotificationList().getNumber()).isEqualTo(STATE_ALLOW); } + private static String getZenLog() { + StringWriter zenLogWriter = new StringWriter(); + ZenLog.dump(new PrintWriter(zenLogWriter), ""); + return zenLogWriter.toString(); + } + private static void withoutWtfCrash(Runnable test) { Log.TerribleFailureHandler oldHandler = Log.setWtfHandler((tag, what, system) -> { }); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index 194d48a80a65..767c02bd268f 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -109,6 +109,7 @@ import com.android.internal.util.test.FakeSettingsProviderRule; import com.android.server.LocalServices; import com.android.server.companion.virtual.VirtualDeviceManagerInternal; import com.android.server.pm.BackgroundUserSoundNotifier; +import com.android.server.pm.UserManagerService; import com.android.server.vibrator.VibrationSession.Status; import org.junit.After; @@ -896,8 +897,8 @@ public class VibratorManagerServiceTest { } @Test - @EnableFlags(android.multiuser.Flags.FLAG_ADD_UI_FOR_SOUNDS_FROM_BACKGROUND_USERS) public void vibrate_thenFgUserRequestsMute_getsCancelled() throws Throwable { + assumeTrue(UserManagerService.shouldShowNotificationForBackgroundUserSounds()); mockVibrators(1); VibratorManagerService service = createSystemReadyService(); @@ -2758,8 +2759,8 @@ public class VibratorManagerServiceTest { } @Test - @EnableFlags(android.multiuser.Flags.FLAG_ADD_UI_FOR_SOUNDS_FROM_BACKGROUND_USERS) public void onExternalVibration_thenFgUserRequestsMute_doNotCancelVibration() throws Throwable { + assumeTrue(UserManagerService.shouldShowNotificationForBackgroundUserSounds()); mockVibrators(1); mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_EXTERNAL_CONTROL); VibratorManagerService service = createSystemReadyService(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java index 22e411ea1500..3f3b24a21d22 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java @@ -202,7 +202,7 @@ public class DisplayAreaPolicyBuilderTest { } @Test - public void testBuilder_defaultPolicy_hasWindowedMagnificationFeature() { + public void testBuilder_defaultPolicy_hasMagnificationFeature() { final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( resourcesWithProvider("")); final DisplayAreaPolicyBuilder.Result defaultPolicy = @@ -210,28 +210,16 @@ public class DisplayAreaPolicyBuilderTest { mRoot, mImeContainer); final List<Feature> features = defaultPolicy.getFeatures(); boolean hasWindowedMagnificationFeature = false; - for (Feature feature : features) { - hasWindowedMagnificationFeature |= feature.getId() == FEATURE_WINDOWED_MAGNIFICATION; - } - - assertThat(hasWindowedMagnificationFeature).isTrue(); - } - - @Test - public void testBuilder_defaultPolicy_hasFullscreenMagnificationFeature() { - final DisplayAreaPolicy.Provider defaultProvider = DisplayAreaPolicy.Provider.fromResources( - resourcesWithProvider("")); - final DisplayAreaPolicyBuilder.Result defaultPolicy = - (DisplayAreaPolicyBuilder.Result) defaultProvider.instantiate(mWms, mDisplayContent, - mRoot, mImeContainer); - final List<Feature> features = defaultPolicy.getFeatures(); boolean hasFullscreenMagnificationFeature = false; for (Feature feature : features) { + hasWindowedMagnificationFeature |= feature.getId() == FEATURE_WINDOWED_MAGNIFICATION; hasFullscreenMagnificationFeature |= feature.getId() == FEATURE_FULLSCREEN_MAGNIFICATION; } - assertThat(hasFullscreenMagnificationFeature).isTrue(); + assertThat(hasWindowedMagnificationFeature).isTrue(); + assertThat(hasFullscreenMagnificationFeature).isEqualTo( + DisplayAreaPolicy.USE_DISPLAY_AREA_FOR_FULLSCREEN_MAGNIFICATION); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java index dc16de1aab5e..523b7235140a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java @@ -36,6 +36,7 @@ import static com.android.server.wm.DragDropController.MSG_UNHANDLED_DROP_LISTEN import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -118,7 +119,8 @@ public class DragDropControllerTests extends WindowTestsBase { static class TestDragDropController extends DragDropController { private Runnable mCloseCallback; - boolean mDeferDragStateClosed; + private boolean mDeferDragStateClosed; + private DragState mPendingCloseDragState; boolean mIsAccessibilityDrag; TestDragDropController(WindowManagerService service, Looper looper) { @@ -135,9 +137,26 @@ public class DragDropControllerTests extends WindowTestsBase { } } + /** + * Caller of this is expected to also call + * {@link TestDragDropController#continueDragStateClose} to properly close and clean up + * DragState. + */ + void deferDragStateClose() { + mDeferDragStateClosed = true; + } + + void continueDragStateClose() { + mDeferDragStateClosed = false; + if (mPendingCloseDragState != null) { + onDragStateClosedLocked(mPendingCloseDragState); + } + } + @Override void onDragStateClosedLocked(DragState dragState) { if (mDeferDragStateClosed) { + mPendingCloseDragState = dragState; return; } super.onDragStateClosedLocked(dragState); @@ -264,7 +283,7 @@ public class DragDropControllerTests extends WindowTestsBase { // Verify after consuming that the drag surface is relinquished try { - mTarget.mDeferDragStateClosed = true; + mTarget.deferDragStateClose(); mTarget.reportDropWindow(mWindow.mInputChannelToken, 0, 0); // Verify the drop event includes the drag surface mTarget.handleMotionEvent(false, mWindow.getDisplayId(), 0, 0); @@ -273,9 +292,9 @@ public class DragDropControllerTests extends WindowTestsBase { mTarget.reportDropResult(iwindow, true); } finally { - mTarget.mDeferDragStateClosed = false; + assertTrue(mTarget.dragSurfaceRelinquishedToDropTarget()); + mTarget.continueDragStateClose(); } - assertTrue(mTarget.dragSurfaceRelinquishedToDropTarget()); }); } @@ -319,12 +338,13 @@ public class DragDropControllerTests extends WindowTestsBase { // Verify the drop event is only sent for the global intercept window assertTrue(nonLocalWindowDragEvents.isEmpty()); - assertTrue(last(localWindowDragEvents).getAction() != ACTION_DROP); - assertTrue(last(globalInterceptWindowDragEvents).getAction() == ACTION_DROP); + assertNotEquals(ACTION_DROP, localWindowDragEvents.getLast().getAction()); + assertEquals(ACTION_DROP, + globalInterceptWindowDragEvents.getLast().getAction()); // Verify that item extras were not sent with the drop event - assertNull(last(localWindowDragEvents).getClipData()); - assertFalse(last(globalInterceptWindowDragEvents).getClipData() + assertNull(localWindowDragEvents.getLast().getClipData()); + assertFalse(globalInterceptWindowDragEvents.getLast().getClipData() .willParcelWithActivityInfo()); }); } @@ -350,7 +370,7 @@ public class DragDropControllerTests extends WindowTestsBase { | View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG)); try { - mTarget.mDeferDragStateClosed = true; + mTarget.deferDragStateClose(); mTarget.reportDropWindow(mWindow.mInputChannelToken, 0, 0); // Verify the drop event does not have the drag flags mTarget.handleMotionEvent(false, mWindow.getDisplayId(), 0, 0); @@ -360,13 +380,13 @@ public class DragDropControllerTests extends WindowTestsBase { mTarget.reportDropResult(iwindow, true); } finally { - mTarget.mDeferDragStateClosed = false; + mTarget.continueDragStateClose(); } }); } @Test - public void testDragEventCoordinates() { + public void testDragEventCoordinatesOverlappingWindows() { int dragStartX = mWindow.getBounds().centerX(); int dragStartY = mWindow.getBounds().centerY(); int startOffsetPx = 10; @@ -401,7 +421,7 @@ public class DragDropControllerTests extends WindowTestsBase { assertEquals(-startOffsetPx, dragEvent2.getY(), 0.0 /* delta */); try { - mTarget.mDeferDragStateClosed = true; + mTarget.deferDragStateClose(); // x, y is window-local coordinate. mTarget.reportDropWindow(window2.mInputChannelToken, dropCoordsPx, dropCoordsPx); @@ -411,7 +431,7 @@ public class DragDropControllerTests extends WindowTestsBase { // Verify only window2 received the DROP event and coords are sent as-is. assertEquals(1, dragEvents.size()); assertEquals(2, dragEvents2.size()); - final DragEvent dropEvent = last(dragEvents2); + final DragEvent dropEvent = dragEvents2.getLast(); assertEquals(ACTION_DROP, dropEvent.getAction()); assertEquals(dropCoordsPx, dropEvent.getX(), 0.0 /* delta */); assertEquals(dropCoordsPx, dropEvent.getY(), 0.0 /* delta */); @@ -419,12 +439,12 @@ public class DragDropControllerTests extends WindowTestsBase { mTarget.reportDropResult(iwindow2, true); // Verify both windows received ACTION_DRAG_ENDED event. - assertEquals(ACTION_DRAG_ENDED, last(dragEvents).getAction()); - assertEquals(window2.getDisplayId(), last(dragEvents).getDisplayId()); - assertEquals(ACTION_DRAG_ENDED, last(dragEvents2).getAction()); - assertEquals(window2.getDisplayId(), last(dragEvents2).getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, dragEvents.getLast().getAction()); + assertEquals(window2.getDisplayId(), dragEvents.getLast().getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, dragEvents2.getLast().getAction()); + assertEquals(window2.getDisplayId(), dragEvents2.getLast().getDisplayId()); } finally { - mTarget.mDeferDragStateClosed = false; + mTarget.continueDragStateClose(); } }); } @@ -463,7 +483,7 @@ public class DragDropControllerTests extends WindowTestsBase { assertEquals(-window2.getBounds().top - 1, dragEvent2.getY(), 0.0 /* delta */); try { - mTarget.mDeferDragStateClosed = true; + mTarget.deferDragStateClose(); mTarget.handleMotionEvent(true, testDisplay.getDisplayId(), dropCoordsPx, dropCoordsPx); // x, y is window-local coordinate. @@ -475,7 +495,7 @@ public class DragDropControllerTests extends WindowTestsBase { // Verify only window2 received the DROP event and coords are sent as-is assertEquals(1, dragEvents.size()); assertEquals(2, dragEvents2.size()); - final DragEvent dropEvent = last(dragEvents2); + final DragEvent dropEvent = dragEvents2.getLast(); assertEquals(ACTION_DROP, dropEvent.getAction()); assertEquals(dropCoordsPx, dropEvent.getX(), 0.0 /* delta */); assertEquals(dropCoordsPx, dropEvent.getY(), 0.0 /* delta */); @@ -483,12 +503,14 @@ public class DragDropControllerTests extends WindowTestsBase { mTarget.reportDropResult(iwindow2, true); // Verify both windows received ACTION_DRAG_ENDED event. - assertEquals(ACTION_DRAG_ENDED, last(dragEvents).getAction()); - assertEquals(testDisplay.getDisplayId(), last(dragEvents).getDisplayId()); - assertEquals(ACTION_DRAG_ENDED, last(dragEvents2).getAction()); - assertEquals(testDisplay.getDisplayId(), last(dragEvents2).getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, dragEvents.getLast().getAction()); + assertEquals(testDisplay.getDisplayId(), + dragEvents.getLast().getDisplayId()); + assertEquals(ACTION_DRAG_ENDED, dragEvents2.getLast().getAction()); + assertEquals(testDisplay.getDisplayId(), + dragEvents2.getLast().getDisplayId()); } finally { - mTarget.mDeferDragStateClosed = false; + mTarget.continueDragStateClose(); } }); } @@ -543,8 +565,23 @@ public class DragDropControllerTests extends WindowTestsBase { }); } - private DragEvent last(ArrayList<DragEvent> list) { - return list.get(list.size() - 1); + @Test + @EnableFlags(Flags.FLAG_ENABLE_CONNECTED_DISPLAYS_DND) + public void testDragCancelledOnTopologyChange() { + // Necessary for now since DragState.sendDragStartedLocked() will recycle drag events + // immediately after dispatching, which is a problem when using mockito arguments captor + // because it returns and modifies the same drag event. + TestIWindow iwindow = (TestIWindow) mWindow.mClient; + final ArrayList<DragEvent> dragEvents = new ArrayList<>(); + iwindow.setDragEventJournal(dragEvents); + + startDrag(0, 0, View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ, + ClipData.newPlainText("label", "text"), (surface) -> { + // Simulate display topology change to trigger drag-and-drop cancellation. + mTarget.handleDisplayTopologyChange(null /* displayTopology */); + assertEquals(2, dragEvents.size()); + assertEquals(ACTION_DRAG_ENDED, dragEvents.getLast().getAction()); + }); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 25b9f4b8035b..8a7e7434e604 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -70,8 +70,6 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserManager; -import android.platform.test.annotations.DisableFlags; -import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArraySet; @@ -82,11 +80,9 @@ import android.window.TaskSnapshot; import androidx.test.filters.MediumTest; -import com.android.launcher3.Flags; import com.android.server.wm.RecentTasks.Callbacks; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -717,18 +713,7 @@ public class RecentTasksTest extends WindowTestsBase { } @Test - @DisableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) - public void testVisibleTasks_excludedFromRecents() { - testVisibleTasks_excludedFromRecents_internal(); - } - - @Test - @EnableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) public void testVisibleTasks_excludedFromRecents_withRefactorFlag() { - testVisibleTasks_excludedFromRecents_internal(); - } - - private void testVisibleTasks_excludedFromRecents_internal() { mRecentTasks.setParameters(-1 /* min */, 4 /* max */, -1 /* ms */); Task invisibleExcludedTask = createTaskBuilder(".ExcludedTask1") @@ -766,19 +751,7 @@ public class RecentTasksTest extends WindowTestsBase { } @Test - @Ignore("b/342627272") - @DisableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) - public void testVisibleTasks_excludedFromRecents_visibleTaskNotFirstTask() { - testVisibleTasks_excludedFromRecents_visibleTaskNotFirstTask_internal(); - } - - @Test - @EnableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) public void testVisibleTasks_excludedFromRecents_visibleTaskNotFirstTask_withRefactorFlag() { - testVisibleTasks_excludedFromRecents_visibleTaskNotFirstTask_internal(); - } - - private void testVisibleTasks_excludedFromRecents_visibleTaskNotFirstTask_internal() { mRecentTasks.setParameters(-1 /* min */, 4 /* max */, -1 /* ms */); Task invisibleExcludedTask = createTaskBuilder(".ExcludedTask1") @@ -816,18 +789,7 @@ public class RecentTasksTest extends WindowTestsBase { } @Test - @DisableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) - public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() { - testVisibleTasks_excludedFromRecents_firstTaskNotVisible_internal(); - } - - @Test - @EnableFlags(Flags.FLAG_ENABLE_USE_TOP_VISIBLE_ACTIVITY_FOR_EXCLUDE_FROM_RECENT_TASK) public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible_withRefactorFlag() { - testVisibleTasks_excludedFromRecents_firstTaskNotVisible_internal(); - } - - private void testVisibleTasks_excludedFromRecents_firstTaskNotVisible_internal() { // Create some set of tasks, some of which are visible and some are not Task homeTask = createTaskBuilder("com.android.pkg1", ".HomeTask") .setParentTask(mTaskContainer.getRootHomeTask()) diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index a95093d7e113..59335d3bb135 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -264,6 +264,7 @@ public class SystemServicesTestRule implements TestRule { spyOn(dmg); doNothing().when(dmg).registerDisplayListener( any(), any(Executor.class), anyLong(), anyString()); + doNothing().when(dmg).registerTopologyListener(any(Executor.class), any(), anyString()); } private void setUpLocalServices() { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index ef58498b351c..546ecc6e38a5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -36,6 +36,7 @@ import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_TOP_OF_TAS import static android.window.TaskFragmentOperation.OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS; +import static android.window.TaskFragmentOperation.OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS; import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK; import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static android.window.TaskFragmentOrganizer.KEY_ERROR_CALLBACK_OP_TYPE; @@ -1911,6 +1912,53 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { OP_TYPE_REORDER_TO_TOP_OF_TASK); } + @Test + public void testApplyTransaction_setCanAffectSystemUiFlags() { + mController.unregisterOrganizer(mIOrganizer); + registerTaskFragmentOrganizer(mIOrganizer, true /* isSystemOrganizer */); + + final Task task = createTask(mDisplayContent); + final TaskFragment tf = createTaskFragment(task); + + // Setting the flag to false. + TaskFragmentOperation operation = new TaskFragmentOperation.Builder( + OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS).setBooleanValue(false).build(); + mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation); + + assertApplyTransactionAllowed(mTransaction); + + verify(tf).setCanAffectSystemUiFlags(false); + + // Setting the flag back to true. + operation = new TaskFragmentOperation.Builder( + OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS).setBooleanValue(true).build(); + mTransaction.addTaskFragmentOperation(tf.getFragmentToken(), operation); + + assertApplyTransactionAllowed(mTransaction); + + verify(tf).setCanAffectSystemUiFlags(true); + } + + @Test + public void testApplyTransaction_setCanAffectSystemUiFlags_failsIfNotSystemOrganizer() { + final Task task = createTask(mDisplayContent); + final TaskFragment tf = createTaskFragment(task); + + TaskFragmentOperation operation = new TaskFragmentOperation.Builder( + OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS).setBooleanValue(false).build(); + mTransaction + .addTaskFragmentOperation(tf.getFragmentToken(), operation) + .setErrorCallbackToken(mErrorToken); + + assertApplyTransactionAllowed(mTransaction); + + // The pending event will be dispatched on the handler (from requestTraversal). + waitHandlerIdle(mWm.mAnimationHandler); + + assertTaskFragmentErrorTransaction(OP_TYPE_SET_CAN_AFFECT_SYSTEM_UI_FLAGS, + SecurityException.class); + } + @NonNull private ActivityRecord setupUntrustedEmbeddingPipReparent() { final int pid = Binder.getCallingPid(); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java index c876663dd749..8a068cc7837a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java @@ -16,9 +16,6 @@ package com.android.server.wm; -import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; -import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION; -import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; import static android.os.Build.HW_TIMEOUT_MULTIPLIER; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -41,10 +38,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Color; -import android.graphics.PixelFormat; -import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; -import android.media.ImageReader; import android.os.Bundle; import android.os.RemoteException; import android.os.SystemClock; @@ -57,13 +51,14 @@ import android.widget.LinearLayout; import androidx.test.filters.MediumTest; import com.android.server.wm.utils.CommonUtils; +import com.android.server.wm.utils.VirtualDisplayTestRule; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.ArrayList; -import java.util.Arrays; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -76,9 +71,9 @@ import java.util.function.Predicate; @MediumTest public class TaskStackChangedListenerTest { + @Rule + public VirtualDisplayTestRule mVirtualDisplayTestRule = new VirtualDisplayTestRule(); private ITaskStackListener mTaskStackListener; - private VirtualDisplay mVirtualDisplay; - private ImageReader mImageReader; private final ArrayList<Activity> mStartedActivities = new ArrayList<>(); private static final int WAIT_TIMEOUT_MS = 5000 * HW_TIMEOUT_MULTIPLIER; @@ -94,10 +89,6 @@ public class TaskStackChangedListenerTest { if (mTaskStackListener != null) { ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener); } - if (mVirtualDisplay != null) { - mVirtualDisplay.release(); - mImageReader.close(); - } // Finish from bottom to top. final int size = mStartedActivities.size(); for (int i = 0; i < size; i++) { @@ -116,21 +107,9 @@ public class TaskStackChangedListenerTest { private VirtualDisplay createVirtualDisplay() { final int width = 800; final int height = 600; - final int density = 160; - final DisplayManager displayManager = getInstrumentation().getContext().getSystemService( - DisplayManager.class); - mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, - 2 /* maxImages */); - final int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY - | VIRTUAL_DISPLAY_FLAG_PUBLIC; final String name = getClass().getSimpleName() + "_VirtualDisplay"; - mVirtualDisplay = displayManager.createVirtualDisplay(name, width, height, density, - mImageReader.getSurface(), flags); - mVirtualDisplay.setSurface(mImageReader.getSurface()); - assertNotNull("display must be registered", - Arrays.stream(displayManager.getDisplays()).filter( - d -> d.getName().equals(name)).findAny()); - return mVirtualDisplay; + return mVirtualDisplayTestRule.createDisplayManagerAttachedVirtualDisplay(name, width, + height); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/VirtualDisplayTestRule.java b/services/tests/wmtests/src/com/android/server/wm/utils/VirtualDisplayTestRule.java new file mode 100644 index 000000000000..e92e6846e161 --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/utils/VirtualDisplayTestRule.java @@ -0,0 +1,92 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm.utils; + +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION; +import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import static org.junit.Assert.assertNotNull; + +import android.graphics.PixelFormat; +import android.hardware.display.DisplayManager; +import android.hardware.display.VirtualDisplay; +import android.media.ImageReader; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** Provides wrapper test rule for creating and managing the cleanup for VirtualDisplay */ +public class VirtualDisplayTestRule implements TestRule { + private static final int DISPLAY_DENSITY = 160; + + private final List<VirtualDisplay> mVirtualDisplays = new ArrayList<>(); + private final List<ImageReader> mImageReaders = new ArrayList<>(); + private final DisplayManager mDisplayManager; + + public VirtualDisplayTestRule() { + mDisplayManager = getInstrumentation().getTargetContext().getSystemService( + DisplayManager.class); + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + base.evaluate(); + } finally { + tearDown(); + } + } + }; + } + + private void tearDown() { + mVirtualDisplays.forEach(VirtualDisplay::release); + mImageReaders.forEach(ImageReader::close); + } + + /** + * The virtual display in WindowTestsBase#createMockSimulatedDisplay is only attached to WM + * DisplayWindowSettingsProvider. DisplayManager is not aware of mock simulated display and + * therefore couldn't be used for actual Display-related testing (e.g. display listeners). + * This method creates real VirtualDisplay through DisplayManager. + */ + public VirtualDisplay createDisplayManagerAttachedVirtualDisplay(String name, int width, + int height) { + final ImageReader imageReader = ImageReader.newInstance(width, height, + PixelFormat.RGBA_8888, 2 /* maxImages */); + mImageReaders.add(imageReader); + final int flags = VIRTUAL_DISPLAY_FLAG_PRESENTATION | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY + | VIRTUAL_DISPLAY_FLAG_PUBLIC; + final VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay(name, width, + height, DISPLAY_DENSITY, imageReader.getSurface(), flags); + mVirtualDisplays.add(virtualDisplay); + assertNotNull("display must be registered", Arrays.stream( + mDisplayManager.getDisplays()).filter(d -> d.getName().equals(name)).findAny()); + return virtualDisplay; + } +} diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java index 819e73df955b..6dda7ea3eb59 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java @@ -48,6 +48,13 @@ public abstract class UsbACTerminal extends UsbACInterface { return mAssocTerminal; } + public boolean isInputTerminal() { + return mTerminalType == UsbTerminalTypes.TERMINAL_IN_MIC + || mTerminalType == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET + || mTerminalType == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED + || mTerminalType == UsbTerminalTypes.TERMINAL_EXTERN_LINE; + } + @Override public int parseRawDescriptors(ByteStream stream) { mTerminalID = stream.getByte(); diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java index ba178845a536..bfa4ecd71f5a 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -524,27 +524,21 @@ public final class UsbDescriptorParser { * @hide */ public boolean hasMic() { - boolean hasMic = false; - ArrayList<UsbDescriptor> acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL, UsbACInterface.AUDIO_AUDIOCONTROL); for (UsbDescriptor descriptor : acDescriptors) { if (descriptor instanceof UsbACTerminal) { UsbACTerminal inDescr = (UsbACTerminal) descriptor; - if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) { - hasMic = true; - break; + if (inDescr.isInputTerminal()) { + return true; } } else { Log.w(TAG, "Undefined Audio Input terminal l: " + descriptor.getLength() + " t:0x" + Integer.toHexString(descriptor.getType())); } } - return hasMic; + return false; } /** @@ -913,18 +907,20 @@ public final class UsbDescriptorParser { float probability = 0.0f; - // Look for a microphone - boolean hasMic = hasMic(); - // Look for a "speaker" boolean hasSpeaker = hasSpeaker(); - if (hasMic && hasSpeaker) { - probability += 0.75f; - } - - if (hasMic && hasHIDInterface()) { - probability += 0.25f; + if (hasMic()) { + if (hasSpeaker) { + probability += 0.75f; + } + if (hasHIDInterface()) { + probability += 0.25f; + } + if (getMaximumInputChannelCount() > 1) { + // A headset is more likely to only support mono capture. + probability -= 0.25f; + } } return probability; @@ -935,9 +931,11 @@ public final class UsbDescriptorParser { * headset. The probability range is between 0.0f (definitely NOT a headset) and * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient * to count on the peripheral being a headset. + * To align with the output device type, only treat the device as input headset if it is + * an output headset. */ public boolean isInputHeadset() { - return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER; + return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER && isOutputHeadset(); } // TODO: Up/Downmix process descriptor is not yet parsed, which may affect the result here. @@ -952,6 +950,32 @@ public final class UsbDescriptorParser { return maxChannelCount; } + private int getMaximumInputChannelCount() { + int maxChannelCount = 0; + ArrayList<UsbDescriptor> acDescriptors = + getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL, + UsbACInterface.AUDIO_AUDIOCONTROL); + for (UsbDescriptor descriptor : acDescriptors) { + if (!(descriptor instanceof UsbACTerminal)) { + continue; + } + UsbACTerminal inDescr = (UsbACTerminal) descriptor; + if (!inDescr.isInputTerminal()) { + continue; + } + // For an input terminal, it should at lease has 1 channel. + // Comparing the max channel count with 1 here in case the USB device doesn't report + // audio channel cluster. + maxChannelCount = Math.max(maxChannelCount, 1); + if (!(descriptor instanceof UsbAudioChannelCluster)) { + continue; + } + maxChannelCount = Math.max(maxChannelCount, + ((UsbAudioChannelCluster) descriptor).getChannelCount()); + } + return maxChannelCount; + } + /** * @hide */ diff --git a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp index ce63fe89fe2e..02b639109931 100644 --- a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp +++ b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp @@ -45,7 +45,6 @@ android_test { ], optimize: { - proguard_compatibility: true, proguard_flags_files: ["proguard.flags"], }, } diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt index 0824874f2a36..9e9d014c622d 100644 --- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt +++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt @@ -280,11 +280,20 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) : .waitForAndVerify() } - /** Click close button on the app header for the given app. */ - fun closeDesktopApp(wmHelper: WindowManagerStateHelper, device: UiDevice) { - val caption = getCaptionForTheApp(wmHelper, device) - val closeButton = caption?.children?.find { it.resourceName.endsWith(CLOSE_BUTTON) } - closeButton?.click() + /** Close a desktop app by clicking the close button on the app header for the given app or by + * pressing back. */ + fun closeDesktopApp( + wmHelper: WindowManagerStateHelper, + device: UiDevice, + usingBackNavigation: Boolean = false + ) { + if (usingBackNavigation) { + device.pressBack() + } else { + val caption = getCaptionForTheApp(wmHelper, device) + val closeButton = caption?.children?.find { it.resourceName.endsWith(CLOSE_BUTTON) } + closeButton?.click() + } wmHelper .StateSyncBuilder() .withAppTransitionIdle() diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt index 8c04f647fb2f..e0532633d40b 100644 --- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt +++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt @@ -736,30 +736,6 @@ class KeyGestureControllerTests { intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ), TestData( - "META + ALT + '-' -> Magnification Zoom Out", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_MINUS - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_OUT, - intArrayOf(KeyEvent.KEYCODE_MINUS), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( - "META + ALT + '=' -> Magnification Zoom In", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_EQUALS - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_ZOOM_IN, - intArrayOf(KeyEvent.KEYCODE_EQUALS), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( "META + ALT + M -> Toggle Magnification", intArrayOf( KeyEvent.KEYCODE_META_LEFT, @@ -784,54 +760,6 @@ class KeyGestureControllerTests { intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ), TestData( - "META + ALT + 'Down' -> Magnification Pan Down", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_DPAD_DOWN - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_DOWN, - intArrayOf(KeyEvent.KEYCODE_DPAD_DOWN), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( - "META + ALT + 'Up' -> Magnification Pan Up", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_DPAD_UP - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_UP, - intArrayOf(KeyEvent.KEYCODE_DPAD_UP), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( - "META + ALT + 'Left' -> Magnification Pan Left", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_DPAD_LEFT - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_LEFT, - intArrayOf(KeyEvent.KEYCODE_DPAD_LEFT), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( - "META + ALT + 'Right' -> Magnification Pan Right", - intArrayOf( - KeyEvent.KEYCODE_META_LEFT, - KeyEvent.KEYCODE_ALT_LEFT, - KeyEvent.KEYCODE_DPAD_RIGHT - ), - KeyGestureEvent.KEY_GESTURE_TYPE_MAGNIFICATION_PAN_RIGHT, - intArrayOf(KeyEvent.KEYCODE_DPAD_RIGHT), - KeyEvent.META_META_ON or KeyEvent.META_ALT_ON, - intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) - ), - TestData( "META + ALT + 'V' -> Toggle Voice Access", intArrayOf( KeyEvent.KEYCODE_META_LEFT, diff --git a/tests/NetworkSecurityConfigTest/Android.bp b/tests/NetworkSecurityConfigTest/Android.bp index 4c48eaa4622e..6a68f2bb7ff9 100644 --- a/tests/NetworkSecurityConfigTest/Android.bp +++ b/tests/NetworkSecurityConfigTest/Android.bp @@ -11,11 +11,12 @@ android_test { name: "NetworkSecurityConfigTests", certificate: "platform", libs: [ - "android.test.runner.stubs.system", "android.test.base.stubs.system", + "android.test.runner.stubs.system", ], static_libs: ["junit"], // Include all test java files. srcs: ["src/**/*.java"], platform_apis: true, + test_suites: ["general-tests"], } diff --git a/tests/NetworkSecurityConfigTest/TEST_MAPPING b/tests/NetworkSecurityConfigTest/TEST_MAPPING new file mode 100644 index 000000000000..d1b9aa1e3b53 --- /dev/null +++ b/tests/NetworkSecurityConfigTest/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "postsubmit": [ + { + "name": "NetworkSecurityConfigTests" + } + ] +} diff --git a/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml index 99106ad37783..5d488410aef7 100644 --- a/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml +++ b/tests/NetworkSecurityConfigTest/res/xml/domain_whitespace.xml @@ -5,7 +5,7 @@ </domain> <domain> developer.android.com </domain> <pin-set> - <pin digest="SHA-256"> zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w= </pin> + <pin digest="SHA-256"> YPtHaftLw6/0vnc2BnNKGF54xiCA28WFcccjkA4ypCM= </pin> </pin-set> </domain-config> </network-security-config> diff --git a/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml index 232f88ff6cc9..731f0f041042 100644 --- a/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml +++ b/tests/NetworkSecurityConfigTest/res/xml/nested_domains.xml @@ -9,7 +9,7 @@ <domain-config> <domain>developer.android.com</domain> <pin-set> - <pin digest="SHA-256">zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w=</pin> + <pin digest="SHA-256">YPtHaftLw6/0vnc2BnNKGF54xiCA28WFcccjkA4ypCM=</pin> </pin-set> </domain-config> </domain-config> diff --git a/tests/NetworkSecurityConfigTest/res/xml/pins1.xml b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml index 7cc81b0101f1..2e49188ec4dc 100644 --- a/tests/NetworkSecurityConfigTest/res/xml/pins1.xml +++ b/tests/NetworkSecurityConfigTest/res/xml/pins1.xml @@ -3,7 +3,7 @@ <domain-config> <domain>android.com</domain> <pin-set> - <pin digest="SHA-256">zCTnfLwLKbS9S2sbp+uFz4KZOocFvXxkV06Ce9O5M2w=</pin> + <pin digest="SHA-256">YPtHaftLw6/0vnc2BnNKGF54xiCA28WFcccjkA4ypCM=</pin> </pin-set> </domain-config> </network-security-config> diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java index c6fe06858e3f..6207a6295ebf 100644 --- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java +++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java @@ -40,9 +40,9 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { super(Activity.class); } - // SHA-256 of the GTS intermediate CA (CN = GTS CA 1C3) for android.com (as of 09/2023). + // SHA-256 of the GTS intermediate CA (CN = WR2) for android.com (as of 01/2025). private static final byte[] GTS_INTERMEDIATE_SPKI_SHA256 = - hexToBytes("cc24e77cbc0b29b4bd4b6b1ba7eb85cf82993a8705bd7c64574e827bd3b9336c"); + hexToBytes("60fb4769fb4bc3aff4be773606734a185e78c62080dbc58571c723900e32a423"); private static final byte[] TEST_CA_BYTES = hexToBytes( diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java index 39b5cb4c4f0d..e140d1a0a94c 100644 --- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java +++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/TestUtils.java @@ -55,6 +55,7 @@ public final class TestUtils { throws Exception { URL url = new URL("https://" + host + ":" + port); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(false); connection.setSSLSocketFactory(context.getSocketFactory()); try { connection.getInputStream(); @@ -68,6 +69,7 @@ public final class TestUtils { throws Exception { URL url = new URL("https://" + host + ":" + port); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(false); connection.setSSLSocketFactory(context.getSocketFactory()); connection.getInputStream(); } diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java index 5db02e376f3d..c11b6bb3435d 100644 --- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java +++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java @@ -284,8 +284,11 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase { // Stop the monitor mIpSecPacketLossDetector.close(); + mIpSecPacketLossDetector.close(); verifyStopped(); - verify(mIpSecTransform).close(); + + verify(mIpSecTransform, never()).close(); + verify(mContext).unregisterReceiver(any()); } @Test diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index a5962292b5b0..82ad9fa05145 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -2778,7 +2778,7 @@ bool ManifestExtractor::Extract(android::IDiagnostics* diag) { auto file_path = it->Next()->GetSource().path.c_str(); const char* last_slash = - android::util::ValidLibraryPathLastSlash(file_path, has_renderscript_bitcode, false); + android::util::ValidLibraryPathLastSlash(file_path, has_renderscript_bitcode); if (last_slash) { architectures_from_apk.insert(std::string(file_path + APK_LIB_LEN, last_slash)); } |