diff options
681 files changed, 8665 insertions, 3114 deletions
diff --git a/Ravenwood.bp b/Ravenwood.bp index b497871aee85..03a23ba15273 100644 --- a/Ravenwood.bp +++ b/Ravenwood.bp @@ -81,7 +81,7 @@ android_ravenwood_libgroup { "hoststubgen-helper-framework-runtime.ravenwood", "junit", "truth", - "ravenwood-junit", + "ravenwood-junit-impl", "android.test.mock", ], } diff --git a/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg b/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg Binary files differnew file mode 100644 index 000000000000..d8b2d759e4c0 --- /dev/null +++ b/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java index f84a0d037ca5..e5a06c9bd146 100644 --- a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java +++ b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java @@ -16,20 +16,29 @@ package android.graphics.perftests; +import static org.junit.Assert.assertTrue; + +import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Color; +import android.graphics.ImageDecoder; import android.graphics.Paint; import android.graphics.RecordingCanvas; import android.graphics.RenderNode; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; +import com.android.perftests.core.R; + import org.junit.Rule; import org.junit.Test; +import java.io.IOException; + @LargeTest public class CanvasPerfTest { @Rule @@ -93,4 +102,38 @@ public class CanvasPerfTest { node.end(canvas); } } + + @Test + public void testCreateScaledBitmap() throws IOException { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Context context = InstrumentationRegistry.getContext(); + Bitmap source = ImageDecoder.decodeBitmap( + ImageDecoder.createSource(context.getResources(), R.drawable.fountain_night), + (decoder, info, source1) -> { + decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); + }); + source.setGainmap(null); + + while (state.keepRunning()) { + Bitmap.createScaledBitmap(source, source.getWidth() / 2, source.getHeight() / 2, true) + .recycle(); + } + } + + @Test + public void testCreateScaledBitmapWithGainmap() throws IOException { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Context context = InstrumentationRegistry.getContext(); + Bitmap source = ImageDecoder.decodeBitmap( + ImageDecoder.createSource(context.getResources(), R.drawable.fountain_night), + (decoder, info, source1) -> { + decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); + }); + assertTrue(source.hasGainmap()); + + while (state.keepRunning()) { + Bitmap.createScaledBitmap(source, source.getWidth() / 2, source.getHeight() / 2, true) + .recycle(); + } + } } diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java index b87e42e31da3..72816e4ce900 100644 --- a/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java +++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowAddRemovePerfTest.java @@ -112,7 +112,7 @@ public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase state.addExtraResult("add", elapsedTimeNsOfAdd); startTime = SystemClock.elapsedRealtimeNanos(); - session.remove(this); + session.remove(asBinder()); final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime; state.addExtraResult("remove", elapsedTimeNsOfRemove); diff --git a/api/Android.bp b/api/Android.bp index 4d56b3748881..e25566aef375 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -81,6 +81,7 @@ combined_apis { "framework-media", "framework-mediaprovider", "framework-ondevicepersonalization", + "framework-pdf", "framework-permission", "framework-permission-s", "framework-scheduling", diff --git a/api/coverage/tools/Android.bp b/api/coverage/tools/Android.bp new file mode 100644 index 000000000000..3e169120dc48 --- /dev/null +++ b/api/coverage/tools/Android.bp @@ -0,0 +1,32 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +java_binary_host { + name: "extract-flagged-apis", + srcs: ["ExtractFlaggedApis.kt"], + main_class: "android.platform.coverage.ExtractFlaggedApisKt", + static_libs: [ + "metalava-signature-reader", + "extract_flagged_apis_proto", + ], +} + +java_library_host { + name: "extract_flagged_apis_proto", + srcs: ["extract_flagged_apis.proto"], + static_libs: ["libprotobuf-java-full"], + proto: { + type: "full", + }, +} diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt new file mode 100644 index 000000000000..948e64f22f20 --- /dev/null +++ b/api/coverage/tools/ExtractFlaggedApis.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.platform.coverage + +import com.android.tools.metalava.model.text.ApiFile +import java.io.File +import java.io.FileWriter + +/** Usage: extract-flagged-apis <api text file> <output .pb file> */ +fun main(args: Array<String>) { + var cb = ApiFile.parseApi(listOf(File(args[0]))) + val flagToApi = mutableMapOf<String, MutableList<String>>() + cb.getPackages() + .allTopLevelClasses() + .filter { it.methods().size > 0 } + .forEach { + for (method in it.methods()) { + val flagValue = + method.modifiers + .findAnnotation("android.annotation.FlaggedApi") + ?.findAttribute("value") + ?.value + ?.value() + if (flagValue != null && flagValue is String) { + val methodQualifiedName = "${it.qualifiedName()}.${method.name()}" + if (flagToApi.containsKey(flagValue)) { + flagToApi.get(flagValue)?.add(methodQualifiedName) + } else { + flagToApi.put(flagValue, mutableListOf(methodQualifiedName)) + } + } + } + } + var builder = FlagApiMap.newBuilder() + for (flag in flagToApi.keys) { + var flaggedApis = FlaggedApis.newBuilder() + for (method in flagToApi.get(flag).orEmpty()) { + flaggedApis.addFlaggedApi(FlaggedApi.newBuilder().setQualifiedName(method)) + } + builder.putFlagToApi(flag, flaggedApis.build()) + } + val flagApiMap = builder.build() + FileWriter(args[1]).use { it.write(flagApiMap.toString()) } +} diff --git a/api/coverage/tools/extract_flagged_apis.proto b/api/coverage/tools/extract_flagged_apis.proto new file mode 100644 index 000000000000..a858108a27b2 --- /dev/null +++ b/api/coverage/tools/extract_flagged_apis.proto @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +package android.platform.coverage; + +option java_multiple_files = true; + +message FlagApiMap { + map<string, FlaggedApis> flag_to_api = 1; +} + +message FlaggedApis { + repeated FlaggedApi flagged_api = 1; +} + +message FlaggedApi { + string qualified_name = 1; +} + diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index 2d235331a672..917529ec1dcf 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -20,6 +20,7 @@ #include <fcntl.h> #include <stdlib.h> #include <string.h> +#include <getopt.h> #include <linux/fb.h> #include <sys/ioctl.h> @@ -32,6 +33,7 @@ #include <ftl/concat.h> #include <ftl/optional.h> +#include <gui/DisplayCaptureArgs.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <gui/SyncScreenCaptureListener.h> @@ -48,14 +50,17 @@ using namespace android; #define COLORSPACE_DISPLAY_P3 2 void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) { - fprintf(stderr, - "usage: %s [-hp] [-d display-id] [FILENAME]\n" - " -h: this message\n" - " -p: save the file as a png.\n" - " -d: specify the display ID to capture%s\n" - " see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n" - "If FILENAME ends with .png it will be saved as a png.\n" - "If FILENAME is not given, the results will be printed to stdout.\n", + fprintf(stderr, R"( +usage: %s [-hp] [-d display-id] [FILENAME] + -h: this message + -p: save the file as a png. + -d: specify the display ID to capture%s + see "dumpsys SurfaceFlinger --display-id" for valid display IDs. + --hint-for-seamless If set will use the hintForSeamless path in SF + +If FILENAME ends with .png it will be saved as a png. +If FILENAME is not given, the results will be printed to stdout. +)", pname, displayIdOpt .transform([](DisplayId id) { @@ -65,6 +70,21 @@ void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) { .c_str()); } +// For options that only exist in long-form. Anything in the +// 0-255 range is reserved for short options (which just use their ASCII value) +namespace LongOpts { +enum { + Reserved = 255, + HintForSeamless, +}; +} + +static const struct option LONG_OPTIONS[] = { + {"png", no_argument, nullptr, 'p'}, + {"help", no_argument, nullptr, 'h'}, + {"hint-for-seamless", no_argument, nullptr, LongOpts::HintForSeamless}, + {0, 0, 0, 0}}; + static int32_t flinger2bitmapFormat(PixelFormat f) { switch (f) { @@ -134,10 +154,11 @@ int main(int argc, char** argv) return 1; } std::optional<DisplayId> displayIdOpt; + gui::CaptureArgs captureArgs; const char* pname = argv[0]; bool png = false; int c; - while ((c = getopt(argc, argv, "phd:")) != -1) { + while ((c = getopt_long(argc, argv, "phd:", LONG_OPTIONS, nullptr)) != -1) { switch (c) { case 'p': png = true; @@ -165,6 +186,9 @@ int main(int argc, char** argv) } usage(pname, displayIdOpt); return 1; + case LongOpts::HintForSeamless: + captureArgs.hintForSeamlessTransition = true; + break; } } @@ -215,7 +239,7 @@ int main(int argc, char** argv) ProcessState::self()->startThreadPool(); sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); - ScreenshotClient::captureDisplay(*displayIdOpt, captureListener); + ScreenshotClient::captureDisplay(*displayIdOpt, captureArgs, captureListener); ScreenCaptureResults captureResults = captureListener->waitForResults(); if (!captureResults.fenceResult.ok()) { diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp index 7659054119c8..ec2b1f4db521 100644 --- a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp +++ b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp @@ -283,7 +283,10 @@ static void configure(JNIEnv* env, jclass /* clazz */, jint handle, jint code, std::vector<int32_t> configs = toVector(env, rawConfigs); // Configure uinput device, with user specified code and value. for (auto& config : configs) { - ::ioctl(static_cast<int>(handle), _IOW(UINPUT_IOCTL_BASE, code, int), config); + if (::ioctl(static_cast<int>(handle), _IOW(UINPUT_IOCTL_BASE, code, int), config) < 0) { + ALOGE("Error configuring device (ioctl %d, value 0x%x): %s", code, config, + strerror(errno)); + } } } diff --git a/cmds/uinput/src/com/android/commands/uinput/Event.java b/cmds/uinput/src/com/android/commands/uinput/Event.java index 01486c0708ce..4498bc2a09d6 100644 --- a/cmds/uinput/src/com/android/commands/uinput/Event.java +++ b/cmds/uinput/src/com/android/commands/uinput/Event.java @@ -30,7 +30,7 @@ import src.com.android.commands.uinput.InputAbsInfo; public class Event { private static final String TAG = "UinputEvent"; - enum Command { + public enum Command { REGISTER, DELAY, INJECT, @@ -188,8 +188,8 @@ public class Event { mEvent.mId = id; } - public void setCommand(String command) { - mEvent.mCommand = Command.valueOf(command.toUpperCase()); + public void setCommand(Command command) { + mEvent.mCommand = command; } public void setName(String name) { diff --git a/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java index 53d0be819dae..a2195c7809be 100644 --- a/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java +++ b/cmds/uinput/src/com/android/commands/uinput/JsonStyleParser.java @@ -57,7 +57,8 @@ public class JsonStyleParser { String name = mReader.nextName(); switch (name) { case "id" -> eb.setId(readInt()); - case "command" -> eb.setCommand(mReader.nextString()); + case "command" -> eb.setCommand( + Event.Command.valueOf(mReader.nextString().toUpperCase())); case "name" -> eb.setName(mReader.nextString()); case "vid" -> eb.setVid(readInt()); case "pid" -> eb.setPid(readInt()); diff --git a/core/api/current.txt b/core/api/current.txt index 30216f76a2cc..b9719e10ea02 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -6904,6 +6904,7 @@ package android.app { public class NotificationManager { method public String addAutomaticZenRule(android.app.AutomaticZenRule); + method @FlaggedApi("android.app.modes_api") public boolean areAutomaticZenRulesUserManaged(); method @Deprecated public boolean areBubblesAllowed(); method public boolean areBubblesEnabled(); method public boolean areNotificationsEnabled(); @@ -10405,7 +10406,7 @@ package android.content { method public abstract java.io.File getDatabasePath(String); method public int getDeviceId(); method public abstract java.io.File getDir(String, int); - method @Nullable public android.view.Display getDisplay(); + method @NonNull public android.view.Display getDisplay(); method @Nullable public final android.graphics.drawable.Drawable getDrawable(@DrawableRes int); method @Nullable public abstract java.io.File getExternalCacheDir(); method public abstract java.io.File[] getExternalCacheDirs(); @@ -39259,7 +39260,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMaxUsageCount(int); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@Nullable java.lang.String...); + method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean); @@ -40545,19 +40546,26 @@ package android.service.notification { public final class Condition implements android.os.Parcelable { ctor public Condition(android.net.Uri, String, int); + ctor @FlaggedApi("android.app.modes_api") public Condition(@Nullable android.net.Uri, @Nullable String, int, int); ctor public Condition(android.net.Uri, String, String, String, int, int, int); + ctor @FlaggedApi("android.app.modes_api") public Condition(@Nullable android.net.Uri, @Nullable String, @Nullable String, @Nullable String, int, int, int, int); ctor public Condition(android.os.Parcel); method public android.service.notification.Condition copy(); method public int describeContents(); method public static boolean isValidId(android.net.Uri, String); method public static android.net.Uri.Builder newId(android.content.Context); method public static String relevanceToString(int); + method @FlaggedApi("android.app.modes_api") @NonNull public static String sourceToString(int); method public static String stateToString(int); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Condition> CREATOR; field public static final int FLAG_RELEVANT_ALWAYS = 2; // 0x2 field public static final int FLAG_RELEVANT_NOW = 1; // 0x1 field public static final String SCHEME = "condition"; + field @FlaggedApi("android.app.modes_api") public static final int SOURCE_CONTEXT = 3; // 0x3 + field @FlaggedApi("android.app.modes_api") public static final int SOURCE_SCHEDULE = 2; // 0x2 + field @FlaggedApi("android.app.modes_api") public static final int SOURCE_UNKNOWN = 0; // 0x0 + field @FlaggedApi("android.app.modes_api") public static final int SOURCE_USER_ACTION = 1; // 0x1 field public static final int STATE_ERROR = 3; // 0x3 field public static final int STATE_FALSE = 0; // 0x0 field public static final int STATE_TRUE = 1; // 0x1 @@ -40567,6 +40575,7 @@ package android.service.notification { field public final android.net.Uri id; field public final String line1; field public final String line2; + field @FlaggedApi("android.app.modes_api") public final int source; field public final int state; field public final String summary; } diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt index 449249e02768..f331e7f5fa84 100644 --- a/core/api/lint-baseline.txt +++ b/core/api/lint-baseline.txt @@ -389,6 +389,12 @@ DeprecationMismatch: javax.microedition.khronos.egl.EGL10#eglCreatePixmapSurface Method javax.microedition.khronos.egl.EGL10.eglCreatePixmapSurface(javax.microedition.khronos.egl.EGLDisplay, javax.microedition.khronos.egl.EGLConfig, Object, int[]): @Deprecated annotation (present) and @deprecated doc tag (not present) do not match +InvalidNullabilityOverride: android.app.Notification.TvExtender#extend(android.app.Notification.Builder) parameter #0: + Invalid nullability on parameter `builder` in method `extend`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.media.midi.MidiUmpDeviceService#onBind(android.content.Intent) parameter #0: + Invalid nullability on parameter `intent` in method `onBind`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. + + RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler): Method 'getAccountsByTypeAndFeatures' documentation mentions permissions without declaring @RequiresPermission RequiresPermission: android.accounts.AccountManager#hasFeatures(android.accounts.Account, String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler): diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index df466ab9b5bb..e7803fbf011d 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -639,3 +639,12 @@ package android.util { } +package android.view.accessibility { + + public final class AccessibilityManager { + method @FlaggedApi("android.view.accessibility.flash_notification_system_api") public boolean startFlashNotificationSequence(@NonNull android.content.Context, int); + method @FlaggedApi("android.view.accessibility.flash_notification_system_api") public boolean stopFlashNotificationSequence(@NonNull android.content.Context); + } + +} + diff --git a/core/api/system-current.txt b/core/api/system-current.txt index afea9b53b49e..6ac8450d607b 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3865,7 +3865,7 @@ package android.content.pm { method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull java.io.File, int) throws android.content.pm.PackageInstaller.PackageParsingException; method @NonNull public android.content.pm.PackageInstaller.InstallInfo readInstallInfo(@NonNull android.os.ParcelFileDescriptor, @Nullable String, int) throws android.content.pm.PackageInstaller.PackageParsingException; method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException; - method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + method @FlaggedApi("android.content.pm.archiving") @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException; method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean); field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL"; field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL"; @@ -3877,6 +3877,7 @@ package android.content.pm { field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS"; field @Deprecated public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH"; field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS"; + field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_ID = "android.content.pm.extra.UNARCHIVE_ID"; field @FlaggedApi("android.content.pm.archiving") public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME"; field public static final int LOCATION_DATA_APP = 0; // 0x0 field public static final int LOCATION_MEDIA_DATA = 2; // 0x2 @@ -3933,6 +3934,7 @@ package android.content.pm { method public void setRequestDowngrade(boolean); method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged(); + method @FlaggedApi("android.content.pm.archiving") public void setUnarchiveId(int); } public class PackageItemInfo { @@ -3991,7 +3993,7 @@ package android.content.pm { method @RequiresPermission(android.Manifest.permission.SET_HARMFUL_APP_WARNINGS) public void setHarmfulAppWarning(@NonNull String, @Nullable CharSequence); method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.SUSPEND_APPS) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable String); method @Nullable @RequiresPermission(value=android.Manifest.permission.SUSPEND_APPS, conditional=true) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo); - method @FlaggedApi("android.content.pm.quarantined_enabled") @Nullable @RequiresPermission(value=android.Manifest.permission.SUSPEND_APPS, conditional=true) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo, int); + method @FlaggedApi("android.content.pm.quarantined_enabled") @Nullable @RequiresPermission(anyOf={android.Manifest.permission.SUSPEND_APPS, android.Manifest.permission.QUARANTINE_APPS}, conditional=true) public String[] setPackagesSuspended(@Nullable String[], boolean, @Nullable android.os.PersistableBundle, @Nullable android.os.PersistableBundle, @Nullable android.content.pm.SuspendDialogInfo, int); method @RequiresPermission(value=android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, conditional=true) public void setSyntheticAppDetailsActivityEnabled(@NonNull String, boolean); method public void setSystemAppState(@NonNull String, int); method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public abstract void setUpdateAvailable(@NonNull String, boolean); @@ -4114,6 +4116,7 @@ package android.content.pm { public static interface PackageManager.OnPermissionsChangedListener { method public void onPermissionsChanged(int); + method @FlaggedApi("android.permission.flags.device_aware_permission_apis") public default void onPermissionsChanged(int, @NonNull String); } @IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME, android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags { diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index 865240207a95..dec1ee52712d 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -517,6 +517,18 @@ GenericException: android.service.autofill.augmented.FillWindow#finalize(): Methods must not throw generic exceptions (`java.lang.Throwable`) +InvalidNullabilityOverride: android.service.textclassifier.TextClassifierService#onUnbind(android.content.Intent) parameter #0: + Invalid nullability on parameter `intent` in method `onUnbind`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.service.voice.HotwordDetectionService#getSystemService(String) parameter #0: + Invalid nullability on parameter `name` in method `getSystemService`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.service.voice.VisualQueryDetectionService#getSystemService(String) parameter #0: + Invalid nullability on parameter `name` in method `getSystemService`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.service.voice.VisualQueryDetectionService#openFileInput(String): + Invalid nullability on method `openFileInput` return. Overrides of unannotated super method cannot be Nullable. +InvalidNullabilityOverride: android.service.voice.VisualQueryDetectionService#openFileInput(String) parameter #0: + Invalid nullability on parameter `filename` in method `openFileInput`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. + + KotlinKeyword: android.app.Notification#when: Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 75797edfb218..93932e4944ad 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -3603,6 +3603,8 @@ package android.view.accessibility { public final class AccessibilityManager { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ACCESSIBILITY) public java.util.List<java.lang.String> getAccessibilityShortcutTargets(int); method public boolean hasAnyDirectConnection(); + method @FlaggedApi("android.view.accessibility.flash_notification_system_api") public boolean startFlashNotificationSequence(@NonNull android.content.Context, int); + method @FlaggedApi("android.view.accessibility.flash_notification_system_api") public boolean stopFlashNotificationSequence(@NonNull android.content.Context); } public class AccessibilityNodeInfo implements android.os.Parcelable { diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index 3a91e25de9e6..bf26bd0a0ec6 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -511,6 +511,16 @@ DeprecationMismatch: javax.microedition.khronos.egl.EGL10#eglCreatePixmapSurface Method javax.microedition.khronos.egl.EGL10.eglCreatePixmapSurface(javax.microedition.khronos.egl.EGLDisplay, javax.microedition.khronos.egl.EGLConfig, Object, int[]): @Deprecated annotation (present) and @deprecated doc tag (not present) do not match +InvalidNullabilityOverride: android.window.WindowProviderService#getSystemService(String) parameter #0: + Invalid nullability on parameter `name` in method `getSystemService`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.window.WindowProviderService#onConfigurationChanged(android.content.res.Configuration) parameter #0: + Invalid nullability on parameter `configuration` in method `onConfigurationChanged`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.window.WindowProviderService#registerComponentCallbacks(android.content.ComponentCallbacks) parameter #0: + Invalid nullability on parameter `callback` in method `registerComponentCallbacks`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. +InvalidNullabilityOverride: android.window.WindowProviderService#unregisterComponentCallbacks(android.content.ComponentCallbacks) parameter #0: + Invalid nullability on parameter `callback` in method `unregisterComponentCallbacks`. Parameters of overrides cannot be NonNull if the super parameter is unannotated. + + KotlinKeyword: android.app.Notification#when: Avoid field names that are Kotlin hard keywords ("when"); see https://android.github.io/kotlin-guides/interop.html#no-hard-keywords diff --git a/core/java/Android.bp b/core/java/Android.bp index 48cafc596d87..dfe3344a466a 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -413,6 +413,10 @@ aidl_interface { backend: { rust: { enabled: true, + apex_available: [ + "//apex_available:platform", + "com.android.virt", + ], }, }, } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index ed18d81d7914..bb335fae887b 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6352,6 +6352,10 @@ public class Activity extends ContextThemeWrapper */ public boolean startActivityIfNeeded(@RequiresPermission @NonNull Intent intent, int requestCode, @Nullable Bundle options) { + if (Instrumentation.DEBUG_START_ACTIVITY) { + Log.d("Instrumentation", "startActivity: intent=" + intent + + " requestCode=" + requestCode + " options=" + options, new Throwable()); + } if (mParent == null) { int result = ActivityManager.START_RETURN_INTENT_TO_CALLER; try { diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index c136db68fd25..02eaf0b3bbd3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -56,7 +56,7 @@ import android.app.backup.BackupAnnotations.BackupDestination; import android.app.backup.BackupAnnotations.OperationType; import android.app.compat.CompatChanges; import android.app.sdksandbox.sandboxactivity.ActivityContextInfo; -import android.app.sdksandbox.sandboxactivity.ActivityContextInfoProvider; +import android.app.sdksandbox.sandboxactivity.SdkSandboxActivityAuthority; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityLifecycleItem.LifecycleState; import android.app.servertransaction.ActivityRelaunchItem; @@ -3795,8 +3795,10 @@ public final class ActivityThread extends ClientTransactionHandler r.activityInfo.targetActivity); } - boolean isSandboxActivityContext = sandboxActivitySdkBasedContext() - && r.intent.isSandboxActivity(mSystemContext); + boolean isSandboxActivityContext = + sandboxActivitySdkBasedContext() + && SdkSandboxActivityAuthority.isSdkSandboxActivity( + mSystemContext, r.intent); boolean isSandboxedSdkContextUsed = false; ContextImpl activityBaseContext; if (isSandboxActivityContext) { @@ -4041,11 +4043,12 @@ public final class ActivityThread extends ClientTransactionHandler */ @Nullable private ContextImpl createBaseContextForSandboxActivity(@NonNull ActivityClientRecord r) { - ActivityContextInfoProvider contextInfoProvider = ActivityContextInfoProvider.getInstance(); + SdkSandboxActivityAuthority sdkSandboxActivityAuthority = + SdkSandboxActivityAuthority.getInstance(); ActivityContextInfo contextInfo; try { - contextInfo = contextInfoProvider.getActivityContextInfo(r.intent); + contextInfo = sdkSandboxActivityAuthority.getActivityContextInfo(r.intent); } catch (IllegalArgumentException e) { Log.e(TAG, "Passed intent does not match an expected sandbox activity", e); return null; diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index a7b29aab4e69..d93544972e7a 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -36,7 +36,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** - * Rule instance information for zen mode. + * Rule instance information for a zen (aka DND or Attention Management) mode. */ public final class AutomaticZenRule implements Parcelable { /* @hide */ @@ -45,7 +45,9 @@ public final class AutomaticZenRule implements Parcelable { private static final int DISABLED = 0; /** - * Rule is of an unknown type. This is the default value if not provided by the owning app. + * Rule is of an unknown type. This is the default value if not provided by the owning app, + * and the value returned if the true type was added in an API level lower than the calling + * app's targetSdk. */ @FlaggedApi(Flags.FLAG_MODES_API) public static final int TYPE_UNKNOWN = -1; @@ -378,7 +380,7 @@ public final class AutomaticZenRule implements Parcelable { * Gets the type of the rule. */ @FlaggedApi(Flags.FLAG_MODES_API) - public int getType() { + public @Type int getType() { return mType; } @@ -594,7 +596,7 @@ public final class AutomaticZenRule implements Parcelable { private ComponentName mOwner; private Uri mConditionId; private int mInterruptionFilter; - private boolean mEnabled; + private boolean mEnabled = true; private ComponentName mConfigurationActivity = null; private ZenPolicy mPolicy = null; private ZenDeviceEffects mDeviceEffects = null; @@ -627,38 +629,63 @@ public final class AutomaticZenRule implements Parcelable { mConditionId = conditionId; } + /** + * Sets the name of this rule. + */ public @NonNull Builder setName(@NonNull String name) { mName = name; return this; } + /** + * Sets the component (service or activity) that owns this rule. + */ public @NonNull Builder setOwner(@Nullable ComponentName owner) { mOwner = owner; return this; } + /** + * Sets the representation of the state that causes this rule to become active. + */ public @NonNull Builder setConditionId(@NonNull Uri conditionId) { mConditionId = conditionId; return this; } + /** + * Sets the interruption filter that is applied when this rule is active. + */ public @NonNull Builder setInterruptionFilter( @InterruptionFilter int interruptionFilter) { mInterruptionFilter = interruptionFilter; return this; } + /** + * Enables this rule. Rules are enabled by default. + */ public @NonNull Builder setEnabled(boolean enabled) { mEnabled = enabled; return this; } + /** + * Sets the configuration activity - an activity that handles + * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows the user more + * information about this rule and/or allows them to configure it. This is required to be + * non-null for rules that are not backed by a + * {@link android.service.notification.ConditionProviderService}. + */ public @NonNull Builder setConfigurationActivity( @Nullable ComponentName configurationActivity) { mConfigurationActivity = configurationActivity; return this; } + /** + * Sets the zen policy. + */ public @NonNull Builder setZenPolicy(@Nullable ZenPolicy policy) { mPolicy = policy; return this; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 08c18c8b7448..4f8e8dd813a1 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -3482,7 +3482,8 @@ class ContextImpl extends Context { mResources = r; // only do this if the user already has more than one preferred locale - if (r.getConfiguration().getLocales().size() > 1) { + if (android.content.res.Flags.defaultLocale() + && r.getConfiguration().getLocales().size() > 1) { LocaleConfig lc = getUserId() < 0 ? LocaleConfig.fromContextIgnoringOverride(this) : new LocaleConfig(this); diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 357ee0a89697..2162e3a77f15 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -43,6 +43,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.TestLooperManager; import android.os.UserHandle; import android.os.UserManager; @@ -67,6 +68,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.StringJoiner; import java.util.concurrent.TimeoutException; /** @@ -100,6 +102,10 @@ public class Instrumentation { private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); + // If set, will print the stack trace for activity starts within the process + static final boolean DEBUG_START_ACTIVITY = Build.IS_DEBUGGABLE && + SystemProperties.getBoolean("persist.wm.debug.start_activity", false); + /** * @hide */ @@ -577,6 +583,9 @@ public class Instrumentation { */ @NonNull public Activity startActivitySync(@NonNull Intent intent, @Nullable Bundle options) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: intent=" + intent + " options=" + options, new Throwable()); + } validateNotAppThread(); final Activity activity; @@ -1891,6 +1900,10 @@ public class Instrumentation { public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: who=" + who + " source=" + target + " intent=" + intent + + " requestCode=" + requestCode + " options=" + options, new Throwable()); + } Objects.requireNonNull(intent); IApplicationThread whoThread = (IApplicationThread) contextThread; Uri referrer = target != null ? target.onProvideReferrer() : null; @@ -1971,6 +1984,14 @@ public class Instrumentation { public int execStartActivitiesAsUser(Context who, IBinder contextThread, IBinder token, Activity target, Intent[] intents, Bundle options, int userId) { + if (DEBUG_START_ACTIVITY) { + StringJoiner joiner = new StringJoiner(", "); + for (Intent i : intents) { + joiner.add(i.toString()); + } + Log.d(TAG, "startActivities: who=" + who + " source=" + target + " userId=" + userId + + " intents=[" + joiner + "] options=" + options, new Throwable()); + } Objects.requireNonNull(intents); for (int i = intents.length - 1; i >= 0; i--) { Objects.requireNonNull(intents[i]); @@ -2055,6 +2076,11 @@ public class Instrumentation { public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: who=" + who + " target=" + target + + " intent=" + intent + " requestCode=" + requestCode + + " options=" + options, new Throwable()); + } Objects.requireNonNull(intent); IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { @@ -2130,6 +2156,11 @@ public class Instrumentation { public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String resultWho, Intent intent, int requestCode, Bundle options, UserHandle user) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: who=" + who + " user=" + user + " intent=" + intent + + " requestCode=" + requestCode + " resultWho=" + resultWho + + " options=" + options, new Throwable()); + } Objects.requireNonNull(intent); IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { @@ -2184,6 +2215,12 @@ public class Instrumentation { Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity, int userId) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: who=" + who + " source=" + target + " userId=" + userId + + " intent=" + intent + " requestCode=" + requestCode + + " ignoreTargetSecurity=" + ignoreTargetSecurity + " options=" + options, + new Throwable()); + } Objects.requireNonNull(intent); IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { @@ -2239,6 +2276,10 @@ public class Instrumentation { public void execStartActivityFromAppTask( Context who, IBinder contextThread, IAppTask appTask, Intent intent, Bundle options) { + if (DEBUG_START_ACTIVITY) { + Log.d(TAG, "startActivity: who=" + who + " intent=" + intent + + " options=" + options, new Throwable()); + } Objects.requireNonNull(intent); IApplicationThread whoThread = (IApplicationThread) contextThread; if (isSdkSandboxAllowedToStartActivities()) { diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 51c937d4e94a..56d0d1f2843d 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1247,6 +1247,22 @@ public class NotificationManager { } /** + * Returns true if users can independently and fully manage {@link AutomaticZenRule} rules. This + * includes the ability to independently activate/deactivate rules and overwrite/freeze the + * behavior (policy) of the rule when activated. + * <p> + * If this method returns true, calls to + * {@link #updateAutomaticZenRule(String, AutomaticZenRule)} may fail and apps should defer + * rule management to system settings/uis. + */ + @FlaggedApi(Flags.FLAG_MODES_API) + public boolean areAutomaticZenRulesUserManaged() { + // modes ui is dependent on modes api + return Flags.modesApi() && Flags.modesUi(); + } + + + /** * Returns AutomaticZenRules owned by the caller. * * <p> diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 3ee9d69229eb..fc3a906ced1d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -17164,6 +17164,7 @@ public class DevicePolicyManager { * * @hide */ + @UnsupportedAppUsage public boolean isOnboardingBugreportV2FlagEnabled() { return onboardingBugreportV2Enabled(); } diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig index d9b521f1a9a8..bf5bad3dc0cf 100644 --- a/core/java/android/app/notification.aconfig +++ b/core/java/android/app/notification.aconfig @@ -8,6 +8,13 @@ flag { } flag { + name: "modes_ui" + namespace: "systemui" + description: "This flag controls new and updated DND UIs; dependent on flag modes_api" + bug: "270703654" +} + +flag { name: "api_tvextender" namespace: "systemui" description: "Guards new android.app.Notification.TvExtender api" diff --git a/core/java/android/app/servertransaction/ActivityLifecycleItem.java b/core/java/android/app/servertransaction/ActivityLifecycleItem.java index 06bff5df490a..48db18f4a1d7 100644 --- a/core/java/android/app/servertransaction/ActivityLifecycleItem.java +++ b/core/java/android/app/servertransaction/ActivityLifecycleItem.java @@ -59,7 +59,7 @@ public abstract class ActivityLifecycleItem extends ActivityTransactionItem { } @Override - boolean isActivityLifecycleItem() { + public boolean isActivityLifecycleItem() { return true; } diff --git a/core/java/android/app/servertransaction/ClientTransactionItem.java b/core/java/android/app/servertransaction/ClientTransactionItem.java index f94e22de06e5..a8d61db1ce3a 100644 --- a/core/java/android/app/servertransaction/ClientTransactionItem.java +++ b/core/java/android/app/servertransaction/ClientTransactionItem.java @@ -75,7 +75,7 @@ public abstract class ClientTransactionItem implements BaseClientRequest, Parcel /** * Whether this is a {@link ActivityLifecycleItem}. */ - boolean isActivityLifecycleItem() { + public boolean isActivityLifecycleItem() { return false; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 1c917ee335af..1c6c7b5baa58 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -7560,7 +7560,7 @@ public abstract class Context { * @throws UnsupportedOperationException if the method is called on an instance that is not * associated with any display. */ - @Nullable + @NonNull public Display getDisplay() { throw new RuntimeException("Not implemented. Must override in a subclass."); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 665ba1119550..c7a86fbe0171 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -12605,8 +12605,12 @@ public class Intent implements Parcelable, Cloneable { return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT; } - // TODO(b/299109198): Refactor into the {@link SdkSandboxManagerLocal} - /** @hide */ + /** + * @deprecated Use {@link SdkSandboxActivityAuthority#isSdkSandboxActivity} instead. + * Once the other API is finalized this method will be removed. + * @hide + */ + @Deprecated @android.ravenwood.annotation.RavenwoodThrow public boolean isSandboxActivity(@NonNull Context context) { if (mAction != null && mAction.equals(ACTION_START_SANDBOXED_ACTIVITY)) { diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java index a4d532712cfe..cb3455b266cd 100644 --- a/core/java/android/content/pm/LauncherActivityInfo.java +++ b/core/java/android/content/pm/LauncherActivityInfo.java @@ -22,11 +22,18 @@ import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; +import android.graphics.Paint; import android.graphics.drawable.Drawable; +import android.icu.text.UnicodeSet; import android.os.UserHandle; import android.os.UserManager; +import android.text.TextUtils; import android.util.DisplayMetrics; +import com.android.internal.annotations.VisibleForTesting; + +import java.util.Objects; + /** * A representation of an activity that can belong to this user or a managed * profile associated with this user. It can be used to query the label, icon @@ -36,6 +43,10 @@ public class LauncherActivityInfo { private final PackageManager mPm; private final LauncherActivityInfoInternal mInternal; + private static final UnicodeSet TRIMMABLE_CHARACTERS = + new UnicodeSet("[[:White_Space:][:Default_Ignorable_Code_Point:][:gc=Cc:]]", + /* ignoreWhitespace= */ false).freeze(); + /** * Create a launchable activity object for a given ResolveInfo and user. * @@ -77,8 +88,22 @@ public class LauncherActivityInfo { * @return The label for the activity. */ public CharSequence getLabel() { + if (!Flags.lightweightInvisibleLabelDetection()) { + // TODO: Go through LauncherAppsService + return getActivityInfo().loadLabel(mPm); + } + + CharSequence label = trim(getActivityInfo().loadLabel(mPm)); + // If the trimmed label is empty, use application's label instead + if (TextUtils.isEmpty(label)) { + label = trim(getApplicationInfo().loadLabel(mPm)); + // If the trimmed label is still empty, use package name instead + if (TextUtils.isEmpty(label)) { + label = getComponentName().getPackageName(); + } + } // TODO: Go through LauncherAppsService - return getActivityInfo().loadLabel(mPm); + return label; } /** @@ -180,4 +205,149 @@ public class LauncherActivityInfo { return mPm.getUserBadgedIcon(originalIcon, mInternal.getUser()); } + + /** + * If the {@code ch} is trimmable, return {@code true}. Otherwise, return + * {@code false}. If the count of the code points of {@code ch} doesn't + * equal 1, return {@code false}. + * <p> + * There are two types of the trimmable characters. + * 1. The character is one of the Default_Ignorable_Code_Point in + * <a href=" + * https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt"> + * DerivedCoreProperties.txt</a>, the White_Space in <a href= + * "https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt">PropList.txt + * </a> or category Cc. + * <p> + * 2. The character is not supported in the current system font. + * {@link android.graphics.Paint#hasGlyph(String)} + * <p> + * + */ + private static boolean isTrimmable(@NonNull Paint paint, @NonNull CharSequence ch) { + Objects.requireNonNull(paint); + Objects.requireNonNull(ch); + + // if ch is empty or it is not a character (i,e, the count of code + // point doesn't equal one), return false + if (TextUtils.isEmpty(ch) + || Character.codePointCount(ch, /* beginIndex= */ 0, ch.length()) != 1) { + return false; + } + + // Return true for the cases as below: + // 1. The character is in the TRIMMABLE_CHARACTERS set + // 2. The character is not supported in the system font + return TRIMMABLE_CHARACTERS.contains(ch) || !paint.hasGlyph(ch.toString()); + } + + /** + * If the {@code sequence} has some leading trimmable characters, creates a new copy + * and removes the trimmable characters from the copy. Otherwise the given + * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)} + * to determine whether the character is trimmable or not. + * + * @return the trimmed string or the original string that has no + * leading trimmable characters. + * @see #isTrimmable(Paint, CharSequence) + * @see #trim(CharSequence) + * @see #trimEnd(CharSequence) + * + * @hide + */ + @VisibleForTesting + @NonNull + public static CharSequence trimStart(@NonNull CharSequence sequence) { + Objects.requireNonNull(sequence); + + if (TextUtils.isEmpty(sequence)) { + return sequence; + } + + final Paint paint = new Paint(); + int trimCount = 0; + final int[] codePoints = sequence.codePoints().toArray(); + for (int i = 0, length = codePoints.length; i < length; i++) { + String ch = new String(new int[]{codePoints[i]}, /* offset= */ 0, /* count= */ 1); + if (!isTrimmable(paint, ch)) { + break; + } + trimCount += ch.length(); + } + if (trimCount == 0) { + return sequence; + } + return sequence.subSequence(trimCount, sequence.length()); + } + + /** + * If the {@code sequence} has some trailing trimmable characters, creates a new copy + * and removes the trimmable characters from the copy. Otherwise the given + * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)} + * to determine whether the character is trimmable or not. + * + * @return the trimmed sequence or the original sequence that has no + * trailing trimmable characters. + * @see #isTrimmable(Paint, CharSequence) + * @see #trimStart(CharSequence) + * @see #trim(CharSequence) + * + * @hide + */ + @VisibleForTesting + @NonNull + public static CharSequence trimEnd(@NonNull CharSequence sequence) { + Objects.requireNonNull(sequence); + + if (TextUtils.isEmpty(sequence)) { + return sequence; + } + + final Paint paint = new Paint(); + int trimCount = 0; + final int[] codePoints = sequence.codePoints().toArray(); + for (int i = codePoints.length - 1; i >= 0; i--) { + String ch = new String(new int[]{codePoints[i]}, /* offset= */ 0, /* count= */ 1); + if (!isTrimmable(paint, ch)) { + break; + } + trimCount += ch.length(); + } + + if (trimCount == 0) { + return sequence; + } + return sequence.subSequence(0, sequence.length() - trimCount); + } + + /** + * If the {@code sequence} has some leading or trailing trimmable characters, creates + * a new copy and removes the trimmable characters from the copy. Otherwise the given + * {@code sequence} is returned as it is. Use {@link #isTrimmable(Paint, CharSequence)} + * to determine whether the character is trimmable or not. + * + * @return the trimmed sequence or the original sequence that has no leading or + * trailing trimmable characters. + * @see #isTrimmable(Paint, CharSequence) + * @see #trimStart(CharSequence) + * @see #trimEnd(CharSequence) + * + * @hide + */ + @VisibleForTesting + @NonNull + public static CharSequence trim(@NonNull CharSequence sequence) { + Objects.requireNonNull(sequence); + + if (TextUtils.isEmpty(sequence)) { + return sequence; + } + + CharSequence result = trimStart(sequence); + if (TextUtils.isEmpty(result)) { + return result; + } + + return trimEnd(result); + } } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 6681e54beaa1..e9a2aaad6579 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -363,6 +363,19 @@ public class PackageInstaller { "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME"; /** + * Extra field for the unarchive ID. Sent as + * part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent. + * + * @see Session#setUnarchiveId(int) + * + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_ARCHIVING) + public static final String EXTRA_UNARCHIVE_ID = + "android.content.pm.extra.UNARCHIVE_ID"; + + /** * If true, the requestor of the unarchival has specified that the app should be unarchived * for {@link android.os.UserHandle#ALL}. * @@ -2268,6 +2281,8 @@ public class PackageInstaller { * @throws PackageManager.NameNotFoundException If {@code packageName} isn't found or not * visible to the caller or if the package has no * installer on the device anymore to unarchive it. + * @throws IOException If parameters were unsatisfiable, such as lack of disk space. + * * @hide */ @RequiresPermission(anyOf = { @@ -2276,11 +2291,12 @@ public class PackageInstaller { @SystemApi @FlaggedApi(Flags.FLAG_ARCHIVING) public void requestUnarchive(@NonNull String packageName) - throws PackageManager.NameNotFoundException { + throws IOException, PackageManager.NameNotFoundException { try { mInstaller.requestUnarchive(packageName, mInstallerPackageName, new UserHandle(mUserId)); } catch (ParcelableException e) { + e.maybeRethrow(IOException.class); e.maybeRethrow(PackageManager.NameNotFoundException.class); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -2548,6 +2564,8 @@ public class PackageInstaller { public boolean applicationEnabledSettingPersistent = false; /** {@hide} */ public int developmentInstallFlags = 0; + /** {@hide} */ + public int unarchiveId = -1; private final ArrayMap<String, Integer> mPermissionStates; @@ -2599,6 +2617,7 @@ public class PackageInstaller { packageSource = source.readInt(); applicationEnabledSettingPersistent = source.readBoolean(); developmentInstallFlags = source.readInt(); + unarchiveId = source.readInt(); } /** {@hide} */ @@ -2632,6 +2651,7 @@ public class PackageInstaller { ret.packageSource = packageSource; ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent; ret.developmentInstallFlags = developmentInstallFlags; + ret.unarchiveId = unarchiveId; return ret; } @@ -3270,6 +3290,22 @@ public class PackageInstaller { } } + /** + * Used to set the unarchive ID received as part of an + * {@link Intent#ACTION_UNARCHIVE_PACKAGE}. + * + * <p> The ID should be retrieved from the unarchive intent and passed into the + * session that's being created to unarchive the app in question. Used to link the unarchive + * intent and the install session to disambiguate. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_ARCHIVING) + @SystemApi + public void setUnarchiveId(int unarchiveId) { + this.unarchiveId = unarchiveId; + } + /** @hide */ @NonNull public ArrayMap<String, Integer> getPermissionStates() { @@ -3327,6 +3363,7 @@ public class PackageInstaller { pw.printPair("applicationEnabledSettingPersistent", applicationEnabledSettingPersistent); pw.printHexPair("developmentInstallFlags", developmentInstallFlags); + pw.printPair("unarchiveId", unarchiveId); pw.println(); } @@ -3370,6 +3407,7 @@ public class PackageInstaller { dest.writeInt(packageSource); dest.writeBoolean(applicationEnabledSettingPersistent); dest.writeInt(developmentInstallFlags); + dest.writeInt(unarchiveId); } public static final Parcelable.Creator<SessionParams> diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 38f137a0a8b3..b5d239beaba9 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -43,6 +43,7 @@ import android.app.PackageInstallObserver; import android.app.PropertyInvalidatedCache; import android.app.admin.DevicePolicyManager; import android.app.usage.StorageStatsManager; +import android.companion.virtual.VirtualDeviceManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; @@ -710,12 +711,31 @@ public abstract class PackageManager { */ @SystemApi public interface OnPermissionsChangedListener { - /** - * Called when the permissions for a UID change. + * Called when the permissions for a UID change for the default device. + * * @param uid The UID with a change. + * @see Context#DEVICE_ID_DEFAULT */ - public void onPermissionsChanged(int uid); + void onPermissionsChanged(int uid); + + /** + * Called when the permissions for a UID change for a device, including virtual devices. + * + * @param uid The UID of permission change event. + * @param persistentDeviceId The persistent device ID of permission change event. + * + * @see VirtualDeviceManager.VirtualDevice#getPersistentDeviceId() + * @see VirtualDeviceManager#PERSISTENT_DEVICE_ID_DEFAULT + */ + @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) + default void onPermissionsChanged(int uid, @NonNull String persistentDeviceId) { + Objects.requireNonNull(persistentDeviceId); + if (Objects.equals(persistentDeviceId, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) { + onPermissionsChanged(uid); + } + } } /** @hide */ @@ -1481,6 +1501,7 @@ public abstract class PackageManager { INSTALL_STAGED, INSTALL_REQUEST_UPDATE_OWNERSHIP, INSTALL_IGNORE_DEXOPT_PROFILE, + INSTALL_UNARCHIVE_DRAFT, }) @Retention(RetentionPolicy.SOURCE) public @interface InstallFlags {} @@ -1725,6 +1746,16 @@ public abstract class PackageManager { public static final int INSTALL_IGNORE_DEXOPT_PROFILE = 1 << 28; /** + * If set, then the session is a draft session created for an upcoming unarchival by its + * installer. + * + * @see PackageInstaller#requestUnarchive(String) + * + * @hide + */ + public static final int INSTALL_UNARCHIVE_DRAFT = 1 << 29; + + /** * Flag parameter for {@link #installPackage} to force a non-staged update of an APEX. This is * a development-only feature and should not be used on end user devices. * @@ -9790,7 +9821,8 @@ public abstract class PackageManager { * launcher to support customization that they might need to handle the suspended state. * * <p>The caller must hold {@link Manifest.permission#SUSPEND_APPS} to use this API except for - * device owner and profile owner. + * device owner and profile owner or the {@link Manifest.permission#QUARANTINE_APPS} if the + * caller is using {@link #FLAG_SUSPEND_QUARANTINED}. * * @param packageNames The names of the packages to set the suspended status. * @param suspended If set to {@code true}, the packages will be suspended, if set to @@ -9818,7 +9850,10 @@ public abstract class PackageManager { */ @SystemApi @FlaggedApi(android.content.pm.Flags.FLAG_QUARANTINED_ENABLED) - @RequiresPermission(value=Manifest.permission.SUSPEND_APPS, conditional=true) + @RequiresPermission(anyOf = { + Manifest.permission.SUSPEND_APPS, + Manifest.permission.QUARANTINE_APPS + }, conditional = true) @SuppressLint("NullableCollection") @Nullable public String[] setPackagesSuspended(@Nullable String[] packageNames, boolean suspended, diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig index 814eae6726a9..bb5fdb714761 100644 --- a/core/java/android/content/pm/flags.aconfig +++ b/core/java/android/content/pm/flags.aconfig @@ -80,3 +80,10 @@ flag { description: "Feature flag to retrieve resolved path of the base APK during an app install." bug: "269728874" } + +flag { + name: "lightweight_invisible_label_detection" + namespace: "package_manager_service" + description: "Feature flag to detect the invisible labels in Launcher Apps" + bug: "299586370" +} diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java index f3194be81b0d..4990a27c48f8 100644 --- a/core/java/android/content/pm/parsing/ApkLite.java +++ b/core/java/android/content/pm/parsing/ApkLite.java @@ -140,6 +140,11 @@ public class ApkLite { private final boolean mIsSdkLibrary; /** + * Indicates if this system app can be updated. + */ + private final boolean mUpdatableSystem; + + /** * Archival install info. */ private final @Nullable ArchivedPackageParcel mArchivedPackage; @@ -154,7 +159,7 @@ public class ApkLite { String requiredSystemPropertyName, String requiredSystemPropertyValue, int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy, Set<String> requiredSplitTypes, Set<String> splitTypes, - boolean hasDeviceAdminReceiver, boolean isSdkLibrary) { + boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean updatableSystem) { mPath = path; mPackageName = packageName; mSplitName = splitName; @@ -188,6 +193,7 @@ public class ApkLite { mRollbackDataPolicy = rollbackDataPolicy; mHasDeviceAdminReceiver = hasDeviceAdminReceiver; mIsSdkLibrary = isSdkLibrary; + mUpdatableSystem = updatableSystem; mArchivedPackage = null; } @@ -225,6 +231,7 @@ public class ApkLite { mRollbackDataPolicy = 0; mHasDeviceAdminReceiver = false; mIsSdkLibrary = false; + mUpdatableSystem = true; mArchivedPackage = archivedPackage; } @@ -535,6 +542,14 @@ public class ApkLite { } /** + * Indicates if this system app can be updated. + */ + @DataClass.Generated.Member + public boolean isUpdatableSystem() { + return mUpdatableSystem; + } + + /** * Archival install info. */ @DataClass.Generated.Member @@ -543,10 +558,10 @@ public class ApkLite { } @DataClass.Generated( - time = 1694792109463L, + time = 1699587291575L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mUpdatableSystem\nprivate final @android.annotation.Nullable android.content.pm.ArchivedPackageParcel mArchivedPackage\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 5f86742fc562..462667926053 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -424,6 +424,7 @@ public class ApkLiteParseUtils { 0); int revisionCode = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE, "revisionCode", 0); boolean coreApp = parser.getAttributeBooleanValue(null, "coreApp", false); + boolean updatableSystem = parser.getAttributeBooleanValue(null, "updatableSystem", true); boolean isolatedSplits = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, "isolatedSplits", false); boolean isFeatureSplit = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, @@ -505,14 +506,18 @@ public class ApkLiteParseUtils { continue; } - if (TAG_PROFILEABLE.equals(parser.getName())) { - profilableByShell = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, - "shell", profilableByShell); - } else if (TAG_RECEIVER.equals(parser.getName())) { - hasDeviceAdminReceiver |= isDeviceAdminReceiver( - parser, hasBindDeviceAdminPermission); - } else if (TAG_SDK_LIBRARY.equals(parser.getName())) { - isSdkLibrary = true; + switch (parser.getName()) { + case TAG_PROFILEABLE: + profilableByShell = parser.getAttributeBooleanValue( + ANDROID_RES_NAMESPACE, "shell", profilableByShell); + break; + case TAG_RECEIVER: + hasDeviceAdminReceiver |= isDeviceAdminReceiver(parser, + hasBindDeviceAdminPermission); + break; + case TAG_SDK_LIBRARY: + isSdkLibrary = true; + break; } } } else if (TAG_OVERLAY.equals(parser.getName())) { @@ -614,7 +619,7 @@ public class ApkLiteParseUtils { overlayIsStatic, overlayPriority, requiredSystemPropertyName, requiredSystemPropertyValue, minSdkVersion, targetSdkVersion, rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second, - hasDeviceAdminReceiver, isSdkLibrary)); + hasDeviceAdminReceiver, isSdkLibrary, updatableSystem)); } private static boolean isDeviceAdminReceiver( diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java index d95924002f1f..4a5c4c8acd25 100644 --- a/core/java/android/hardware/usb/UsbPortStatus.java +++ b/core/java/android/hardware/usb/UsbPortStatus.java @@ -646,12 +646,7 @@ public final class UsbPortStatus implements Parcelable { * @return array including {@link #COMPLIANCE_WARNING_OTHER}, * {@link #COMPLIANCE_WARNING_DEBUG_ACCESSORY}, * {@link #COMPLIANCE_WARNING_BC_1_2}, - * {@link #COMPLIANCE_WARNING_MISSING_RP}, - * {@link #COMPLIANCE_WARNING_INPUT_POWER_LIMITED}, - * {@link #COMPLIANCE_WARNING_MISSING_DATA_LINES}, - * {@link #COMPLIANCE_WARNING_ENUMERATION_FAIL}, - * {@link #COMPLIANCE_WARNING_FLAKY_CONNECTION}, - * {@link #COMPLIANCE_WARNING_UNRELIABLE_IO}. + * {@link #COMPLIANCE_WARNING_MISSING_RP}. */ @CheckResult @NonNull diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java index f16e2439f3f4..e2d215ebfed4 100644 --- a/core/java/android/inputmethodservice/AbstractInputMethodService.java +++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java @@ -33,6 +33,8 @@ import android.view.inputmethod.InputMethod; import android.view.inputmethod.InputMethodSession; import android.window.WindowProviderService; +import com.android.internal.annotations.VisibleForTesting; + import java.io.FileDescriptor; import java.io.PrintWriter; @@ -72,8 +74,9 @@ public abstract class AbstractInputMethodService extends WindowProviderService * {@code null} if {@link #onCreateInputMethodInterface()} is not yet called. * @hide */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @Nullable - protected final InputMethod getInputMethodInternal() { + public final InputMethod getInputMethodInternal() { return mInputMethod; } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index ba80811e198c..18d3e5e02fbe 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -149,6 +149,7 @@ import android.window.OnBackInvokedDispatcher; import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback; import com.android.internal.inputmethod.IInputContentUriToken; import com.android.internal.inputmethod.IInputMethod; @@ -3997,6 +3998,16 @@ public class InputMethodService extends AbstractInputMethodService { } /** + * Returns whether the IME navigation bar is currently shown, for testing purposes. + * + * @hide + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + public final boolean isImeNavigationBarShownForTesting() { + return mNavigationBarController.isShown(); + } + + /** * Used to inject custom {@link InputMethodServiceInternal}. * * @return the {@link InputMethodServiceInternal} to be used. diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java index 8be4c5858694..9c55b0ee0623 100644 --- a/core/java/android/inputmethodservice/NavigationBarController.java +++ b/core/java/android/inputmethodservice/NavigationBarController.java @@ -77,6 +77,10 @@ final class NavigationBarController { default void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) { } + default boolean isShown() { + return false; + } + default String toDebugString() { return "No-op implementation"; } @@ -117,6 +121,13 @@ final class NavigationBarController { mImpl.onNavButtonFlagsChanged(navButtonFlags); } + /** + * Returns whether the IME navigation bar is currently shown. + */ + boolean isShown() { + return mImpl.isShown(); + } + String toDebugString() { return mImpl.toDebugString(); } @@ -561,6 +572,12 @@ final class NavigationBarController { } @Override + public boolean isShown() { + return mNavigationBarFrame != null + && mNavigationBarFrame.getVisibility() == View.VISIBLE; + } + + @Override public String toDebugString() { return "{mImeDrawsImeNavBar=" + mImeDrawsImeNavBar + " mNavigationBarFrame=" + mNavigationBarFrame diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index a5f8844a2921..cd52b5c0f7f3 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -115,6 +115,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable { static final String XML_ATTR_HIGHEST_DRAIN_PACKAGE = "highest_drain_package"; static final String XML_ATTR_TIME_IN_FOREGROUND = "time_in_foreground"; static final String XML_ATTR_TIME_IN_BACKGROUND = "time_in_background"; + static final String XML_ATTR_TIME_IN_FOREGROUND_SERVICE = "time_in_foreground_service"; // We need about 700 bytes per UID private static final long BATTERY_CONSUMER_CURSOR_WINDOW_SIZE = 5_000 * 700; diff --git a/core/java/android/os/DeadObjectException.java b/core/java/android/os/DeadObjectException.java index 65ed618fb075..61aa222ef482 100644 --- a/core/java/android/os/DeadObjectException.java +++ b/core/java/android/os/DeadObjectException.java @@ -19,8 +19,29 @@ import android.os.RemoteException; /** * The object you are calling has died, because its hosting process - * no longer exists. This is also thrown for low-level binder - * errors. + * no longer exists, or there has been a low-level binder error. + * + * If you get this exception from a system service, the error is + * usually nonrecoverable as the framework will restart. If you + * receive this error from an app, at a minimum, you should + * recover by resetting the connection. For instance, you should + * drop the binder, clean up associated state, and reset your + * connection to the service which through this error. In order + * to simplify your error recovery paths, you may also want to + * "simply" restart your process. However, this may not be an + * option if the service you are talking to is unreliable or + * crashes frequently. + * + * If this isn't from a service death and is instead from a + * low-level binder error, it will be from: + * - a oneway call queue filling up (too many oneway calls) + * - from the binder buffer being filled up, so that the transaction + * is rejected. + * + * In these cases, more information about the error will be + * logged. However, there isn't a good way to differentiate + * this information at runtime. So, you should handle the + * error, as if the service died. */ public class DeadObjectException extends RemoteException { public DeadObjectException() { diff --git a/core/java/android/os/DeadSystemRuntimeException.java b/core/java/android/os/DeadSystemRuntimeException.java index 82b1ad8a8630..3b107984cebf 100644 --- a/core/java/android/os/DeadSystemRuntimeException.java +++ b/core/java/android/os/DeadSystemRuntimeException.java @@ -19,10 +19,12 @@ package android.os; /** * Exception thrown when a call into system_server resulted in a * DeadObjectException, meaning that the system_server has died or - * experienced a low-level binder error. There's * nothing apps can + * experienced a low-level binder error. There's nothing apps can * do at this point - the system will automatically restart - so * there's no point in catching this. * + * See {@link android.os.DeadObjectException}. + * * @hide */ public class DeadSystemRuntimeException extends RuntimeException { diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java index 03a1b6f7fe01..3eea94eaf2e6 100644 --- a/core/java/android/os/UidBatteryConsumer.java +++ b/core/java/android/os/UidBatteryConsumer.java @@ -71,7 +71,8 @@ public final class UidBatteryConsumer extends BatteryConsumer { static final int COLUMN_INDEX_PACKAGE_WITH_HIGHEST_DRAIN = COLUMN_INDEX_UID + 1; static final int COLUMN_INDEX_TIME_IN_FOREGROUND = COLUMN_INDEX_UID + 2; static final int COLUMN_INDEX_TIME_IN_BACKGROUND = COLUMN_INDEX_UID + 3; - static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 4; + static final int COLUMN_INDEX_TIME_IN_FOREGROUND_SERVICE = COLUMN_INDEX_UID + 4; + static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 5; UidBatteryConsumer(BatteryConsumerData data) { super(data); @@ -92,17 +93,35 @@ public final class UidBatteryConsumer extends BatteryConsumer { /** * Returns the amount of time in milliseconds this UID spent in the specified state. + * @deprecated use {@link #getTimeInProcessStateMs} instead. */ + @Deprecated public long getTimeInStateMs(@State int state) { switch (state) { case STATE_BACKGROUND: - return mData.getInt(COLUMN_INDEX_TIME_IN_BACKGROUND); + return mData.getInt(COLUMN_INDEX_TIME_IN_BACKGROUND) + + mData.getInt(COLUMN_INDEX_TIME_IN_FOREGROUND_SERVICE); case STATE_FOREGROUND: return mData.getInt(COLUMN_INDEX_TIME_IN_FOREGROUND); } return 0; } + /** + * Returns the amount of time in milliseconds this UID spent in the specified process state. + */ + public long getTimeInProcessStateMs(@ProcessState int state) { + switch (state) { + case PROCESS_STATE_BACKGROUND: + return mData.getInt(COLUMN_INDEX_TIME_IN_BACKGROUND); + case PROCESS_STATE_FOREGROUND: + return mData.getInt(COLUMN_INDEX_TIME_IN_FOREGROUND); + case PROCESS_STATE_FOREGROUND_SERVICE: + return mData.getInt(COLUMN_INDEX_TIME_IN_FOREGROUND_SERVICE); + } + return 0; + } + @Override public void dump(PrintWriter pw, boolean skipEmptyComponents) { pw.print("UID "); @@ -158,9 +177,11 @@ public final class UidBatteryConsumer extends BatteryConsumer { packageWithHighestDrain); } serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND, - getTimeInStateMs(STATE_FOREGROUND)); + getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND)); serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND, - getTimeInStateMs(STATE_BACKGROUND)); + getTimeInProcessStateMs(PROCESS_STATE_BACKGROUND)); + serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND_SERVICE, + getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE)); mPowerComponents.writeToXml(serializer); serializer.endTag(null, BatteryUsageStats.XML_TAG_UID); } @@ -180,10 +201,13 @@ public final class UidBatteryConsumer extends BatteryConsumer { consumerBuilder.setPackageWithHighestDrain( parser.getAttributeValue(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE)); - consumerBuilder.setTimeInStateMs(STATE_FOREGROUND, + consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND, parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND)); - consumerBuilder.setTimeInStateMs(STATE_BACKGROUND, + consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND, parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND)); + consumerBuilder.setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE, + parser.getAttributeLong(null, + BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND_SERVICE)); while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(BatteryUsageStats.XML_TAG_UID)) && eventType != XmlPullParser.END_DOCUMENT) { @@ -255,7 +279,9 @@ public final class UidBatteryConsumer extends BatteryConsumer { /** * Sets the duration, in milliseconds, that this UID was active in a particular state, * such as foreground or background. + * @deprecated use {@link #setTimeInProcessStateMs} instead. */ + @Deprecated @NonNull public Builder setTimeInStateMs(@State int state, long timeInStateMs) { switch (state) { @@ -272,6 +298,28 @@ public final class UidBatteryConsumer extends BatteryConsumer { } /** + * Sets the duration, in milliseconds, that this UID was active in a particular process + * state, such as foreground service. + */ + @NonNull + public Builder setTimeInProcessStateMs(@ProcessState int state, long timeInProcessStateMs) { + switch (state) { + case PROCESS_STATE_FOREGROUND: + mData.putLong(COLUMN_INDEX_TIME_IN_FOREGROUND, timeInProcessStateMs); + break; + case PROCESS_STATE_BACKGROUND: + mData.putLong(COLUMN_INDEX_TIME_IN_BACKGROUND, timeInProcessStateMs); + break; + case PROCESS_STATE_FOREGROUND_SERVICE: + mData.putLong(COLUMN_INDEX_TIME_IN_FOREGROUND_SERVICE, timeInProcessStateMs); + break; + default: + throw new IllegalArgumentException("Unsupported process state: " + state); + } + return this; + } + + /** * Marks the UidBatteryConsumer for exclusion from the result set. */ public Builder excludeFromBatteryUsageStats() { @@ -285,12 +333,15 @@ public final class UidBatteryConsumer extends BatteryConsumer { public Builder add(UidBatteryConsumer consumer) { mPowerComponentsBuilder.addPowerAndDuration(consumer.mPowerComponents); - setTimeInStateMs(STATE_FOREGROUND, + setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND, mData.getLong(COLUMN_INDEX_TIME_IN_FOREGROUND) - + consumer.getTimeInStateMs(STATE_FOREGROUND)); - setTimeInStateMs(STATE_BACKGROUND, + + consumer.getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND)); + setTimeInProcessStateMs(PROCESS_STATE_BACKGROUND, mData.getLong(COLUMN_INDEX_TIME_IN_BACKGROUND) - + consumer.getTimeInStateMs(STATE_BACKGROUND)); + + consumer.getTimeInProcessStateMs(PROCESS_STATE_BACKGROUND)); + setTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE, + mData.getLong(COLUMN_INDEX_TIME_IN_FOREGROUND_SERVICE) + + consumer.getTimeInProcessStateMs(PROCESS_STATE_FOREGROUND_SERVICE)); if (mPackageWithHighestDrain == PACKAGE_NAME_UNINITIALIZED) { mPackageWithHighestDrain = consumer.getPackageWithHighestDrain(); diff --git a/core/java/android/permission/IOnPermissionsChangeListener.aidl b/core/java/android/permission/IOnPermissionsChangeListener.aidl index cc52a7210737..afacf1a74ca6 100644 --- a/core/java/android/permission/IOnPermissionsChangeListener.aidl +++ b/core/java/android/permission/IOnPermissionsChangeListener.aidl @@ -21,5 +21,5 @@ package android.permission; * {@hide} */ oneway interface IOnPermissionsChangeListener { - void onPermissionsChanged(int uid); + void onPermissionsChanged(int uid, String deviceId); } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index e10ea10e2a29..7a158c548a38 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -1725,7 +1725,7 @@ public final class PermissionManager { } private final class OnPermissionsChangeListenerDelegate - extends IOnPermissionsChangeListener.Stub implements Handler.Callback{ + extends IOnPermissionsChangeListener.Stub implements Handler.Callback { private static final int MSG_PERMISSIONS_CHANGED = 1; private final PackageManager.OnPermissionsChangedListener mListener; @@ -1738,8 +1738,8 @@ public final class PermissionManager { } @Override - public void onPermissionsChanged(int uid) { - mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); + public void onPermissionsChanged(int uid, String deviceId) { + mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget(); } @Override @@ -1747,7 +1747,8 @@ public final class PermissionManager { switch (msg.what) { case MSG_PERMISSIONS_CHANGED: { final int uid = msg.arg1; - mListener.onPermissionsChanged(uid); + final String deviceId = msg.obj.toString(); + mListener.onPermissionsChanged(uid, deviceId); return true; } default: diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 9bdd0c2db779..0133bd822182 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -36,10 +36,3 @@ flag { description: "Collect sepolicy hash from sysfs" bug: "308471499" } - -flag { - name: "extend_ecm_to_all_settings" - namespace: "responsible_apis" - description: "Allow all app settings to be restrictable via configuration" - bug: "297372999" -} diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig new file mode 100644 index 000000000000..4e5588cce1c9 --- /dev/null +++ b/core/java/android/security/responsible_apis_flags.aconfig @@ -0,0 +1,22 @@ +package: "android.security" + +flag { + name: "extend_ecm_to_all_settings" + namespace: "responsible_apis" + description: "Allow all app settings to be restrictable via configuration" + bug: "297372999" +} + +flag { + name: "asm_restrictions_enabled" + namespace: "responsible_apis" + description: "Enables ASM restrictions for activity starts and finishes" + bug: "230590090" +} + +flag { + name: "asm_toasts_enabled" + namespace: "responsible_apis" + description: "Enables toasts when ASM restrictions are triggered" + bug: "230590090" +} diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java index 4d33bfd1e94a..d76fa5be4940 100644 --- a/core/java/android/service/notification/Condition.java +++ b/core/java/android/service/notification/Condition.java @@ -16,8 +16,11 @@ package android.service.notification; +import android.annotation.FlaggedApi; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.Flags; import android.content.Context; import android.net.Uri; import android.os.Parcel; @@ -57,7 +60,6 @@ public final class Condition implements Parcelable { * Indicates that Do Not Disturb should be turned on. */ public static final int STATE_TRUE = 1; - public static final int STATE_UNKNOWN = 2; public static final int STATE_ERROR = 3; @@ -90,6 +92,33 @@ public final class Condition implements Parcelable { public final int flags; public final int icon; + /** @hide */ + @IntDef(prefix = { "SOURCE_" }, value = { + SOURCE_UNKNOWN, + SOURCE_USER_ACTION, + SOURCE_SCHEDULE, + SOURCE_CONTEXT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Source {} + + /** The state is changing due to an unknown reason. */ + @FlaggedApi(Flags.FLAG_MODES_API) + public static final int SOURCE_UNKNOWN = 0; + /** The state is changing due to an explicit user action. */ + @FlaggedApi(Flags.FLAG_MODES_API) + public static final int SOURCE_USER_ACTION = 1; + /** The state is changing due to an automatic schedule (alarm, set time, etc). */ + @FlaggedApi(Flags.FLAG_MODES_API) + public static final int SOURCE_SCHEDULE = 2; + /** The state is changing due to a change in context (such as detected driving or sleeping). */ + @FlaggedApi(Flags.FLAG_MODES_API) + public static final int SOURCE_CONTEXT = 3; + + /** The source of, or reason for, the state change represented by this Condition. **/ + @FlaggedApi(Flags.FLAG_MODES_API) + public final @Source int source; + /** * The maximum string length for any string contained in this condition. * @hide @@ -99,14 +128,48 @@ public final class Condition implements Parcelable { /** * An object representing the current state of a {@link android.app.AutomaticZenRule}. * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule - * @param summary a user visible description of the rule state. + * @param summary a user visible description of the rule state + * @param state whether the mode should be activated or deactivated */ + // TODO: b/310208502 - Deprecate this in favor of constructor which specifies source. public Condition(Uri id, String summary, int state) { - this(id, summary, "", "", -1, state, FLAG_RELEVANT_ALWAYS); + this(id, summary, "", "", -1, state, SOURCE_UNKNOWN, FLAG_RELEVANT_ALWAYS); + } + + /** + * An object representing the current state of a {@link android.app.AutomaticZenRule}. + * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule + * @param summary a user visible description of the rule state + * @param state whether the mode should be activated or deactivated + * @param source the source of, or reason for, the state change represented by this Condition + */ + @FlaggedApi(Flags.FLAG_MODES_API) + public Condition(@Nullable Uri id, @Nullable String summary, @State int state, + @Source int source) { + this(id, summary, "", "", -1, state, source, FLAG_RELEVANT_ALWAYS); } + // TODO: b/310208502 - Deprecate this in favor of constructor which specifies source. public Condition(Uri id, String summary, String line1, String line2, int icon, int state, int flags) { + this(id, summary, line1, line2, icon, state, SOURCE_UNKNOWN, flags); + } + + /** + * An object representing the current state of a {@link android.app.AutomaticZenRule}. + * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule + * @param summary a user visible description of the rule state + * @param line1 a user-visible description of when the rule will end + * @param line2 a continuation of the user-visible description of when the rule will end + * @param icon an icon representing this condition + * @param state whether the mode should be activated or deactivated + * @param source the source of, or reason for, the state change represented by this Condition + * @param flags flags on this condition + */ + @FlaggedApi(Flags.FLAG_MODES_API) + public Condition(@Nullable Uri id, @Nullable String summary, @Nullable String line1, + @Nullable String line2, int icon, @State int state, @Source int source, + int flags) { if (id == null) throw new IllegalArgumentException("id is required"); if (summary == null) throw new IllegalArgumentException("summary is required"); if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state); @@ -116,6 +179,7 @@ public final class Condition implements Parcelable { this.line2 = getTrimmedString(line2); this.icon = icon; this.state = state; + this.source = source; this.flags = flags; } @@ -129,6 +193,7 @@ public final class Condition implements Parcelable { source.readString(), source.readInt(), source.readInt(), + Flags.modesApi() ? source.readInt() : SOURCE_UNKNOWN, source.readInt()); } @@ -144,20 +209,27 @@ public final class Condition implements Parcelable { dest.writeString(line2); dest.writeInt(icon); dest.writeInt(state); + if (Flags.modesApi()) { + dest.writeInt(this.source); + } dest.writeInt(this.flags); } @Override public String toString() { - return new StringBuilder(Condition.class.getSimpleName()).append('[') + StringBuilder sb = new StringBuilder(Condition.class.getSimpleName()).append('[') .append("state=").append(stateToString(state)) .append(",id=").append(id) .append(",summary=").append(summary) .append(",line1=").append(line1) .append(",line2=").append(line2) - .append(",icon=").append(icon) - .append(",flags=").append(flags) + .append(",icon=").append(icon); + if (Flags.modesApi()) { + sb.append(",source=").append(sourceToString(source)); + } + return sb.append(",flags=").append(flags) .append(']').toString(); + } /** @hide */ @@ -171,6 +243,7 @@ public final class Condition implements Parcelable { proto.write(ConditionProto.LINE_2, line2); proto.write(ConditionProto.ICON, icon); proto.write(ConditionProto.STATE, state); + // TODO: b/310644464 - Add source to dump. proto.write(ConditionProto.FLAGS, flags); proto.end(token); @@ -184,6 +257,16 @@ public final class Condition implements Parcelable { throw new IllegalArgumentException("state is invalid: " + state); } + /** Provides a human-readable string version of the Source enum. */ + @FlaggedApi(Flags.FLAG_MODES_API) + public static @NonNull String sourceToString(@Source int source) { + if (source == SOURCE_UNKNOWN) return "SOURCE_UNKNOWN"; + if (source == SOURCE_USER_ACTION) return "SOURCE_USER_ACTION"; + if (source == SOURCE_SCHEDULE) return "SOURCE_SCHEDULE"; + if (source == SOURCE_CONTEXT) return "SOURCE_CONTEXT"; + throw new IllegalArgumentException("source is invalid: " + source); + } + public static String relevanceToString(int flags) { final boolean now = (flags & FLAG_RELEVANT_NOW) != 0; final boolean always = (flags & FLAG_RELEVANT_ALWAYS) != 0; @@ -197,17 +280,24 @@ public final class Condition implements Parcelable { if (!(o instanceof Condition)) return false; if (o == this) return true; final Condition other = (Condition) o; - return Objects.equals(other.id, id) + boolean finalEquals = Objects.equals(other.id, id) && Objects.equals(other.summary, summary) && Objects.equals(other.line1, line1) && Objects.equals(other.line2, line2) && other.icon == icon && other.state == state && other.flags == flags; + if (Flags.modesApi()) { + return finalEquals && other.source == source; + } + return finalEquals; } @Override public int hashCode() { + if (Flags.modesApi()) { + return Objects.hash(id, summary, line1, line2, icon, state, source, flags); + } return Objects.hash(id, summary, line1, line2, icon, state, flags); } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 305b751f0cef..fedad895961d 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -160,6 +160,7 @@ public class ZenModeConfig implements Parcelable { private static final String CONDITION_ATT_LINE2 = "line2"; private static final String CONDITION_ATT_ICON = "icon"; private static final String CONDITION_ATT_STATE = "state"; + private static final String CONDITION_ATT_SOURCE = "source"; private static final String CONDITION_ATT_FLAGS = "flags"; private static final String ZEN_POLICY_TAG = "zen_policy"; @@ -687,7 +688,12 @@ public class ZenModeConfig implements Parcelable { final int state = safeInt(parser, CONDITION_ATT_STATE, -1); final int flags = safeInt(parser, CONDITION_ATT_FLAGS, -1); try { - return new Condition(id, summary, line1, line2, icon, state, flags); + if (Flags.modesApi()) { + final int source = safeInt(parser, CONDITION_ATT_SOURCE, Condition.SOURCE_UNKNOWN); + return new Condition(id, summary, line1, line2, icon, state, source, flags); + } else { + return new Condition(id, summary, line1, line2, icon, state, flags); + } } catch (IllegalArgumentException e) { Slog.w(TAG, "Unable to read condition xml", e); return null; @@ -701,6 +707,9 @@ public class ZenModeConfig implements Parcelable { out.attribute(null, CONDITION_ATT_LINE2, c.line2); out.attributeInt(null, CONDITION_ATT_ICON, c.icon); out.attributeInt(null, CONDITION_ATT_STATE, c.state); + if (Flags.modesApi()) { + out.attributeInt(null, CONDITION_ATT_SOURCE, c.source); + } out.attributeInt(null, CONDITION_ATT_FLAGS, c.flags); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index bf09ec181c1f..54116a2749e0 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -2289,7 +2289,7 @@ public abstract class WallpaperService extends Service { mInputEventReceiver = null; } - mSession.remove(mWindow); + mSession.remove(mWindow.asBinder()); } catch (RemoteException e) { } mSurfaceHolder.mSurface.release(); diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 77e616b358cb..2105420b84cd 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -118,6 +118,7 @@ public class StaticLayout extends Layout { b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE; b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE; b.mLineBreakConfig = LineBreakConfig.NONE; + b.mMinimumFontMetrics = null; return b; } @@ -130,6 +131,7 @@ public class StaticLayout extends Layout { b.mText = null; b.mLeftIndents = null; b.mRightIndents = null; + b.mMinimumFontMetrics = null; sPool.release(b); } @@ -139,6 +141,7 @@ public class StaticLayout extends Layout { mPaint = null; mLeftIndents = null; mRightIndents = null; + mMinimumFontMetrics = null; } public Builder setText(CharSequence source) { diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index c0a5629f9220..6ea462eb969f 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -68,6 +68,7 @@ import android.text.style.TypefaceSpan; import android.text.style.URLSpan; import android.text.style.UnderlineSpan; import android.text.style.UpdateAppearance; +import android.util.EmptyArray; import android.util.Log; import android.util.Printer; import android.view.View; @@ -141,9 +142,9 @@ public class TextUtils { return (method == TextUtils.TruncateAt.END_SMALL) ? ELLIPSIS_TWO_DOTS : ELLIPSIS_NORMAL; } - private TextUtils() { /* cannot be instantiated */ } + @android.ravenwood.annotation.RavenwoodKeep public static void getChars(CharSequence s, int start, int end, char[] dest, int destoff) { Class<? extends CharSequence> c = s.getClass(); @@ -162,10 +163,12 @@ public class TextUtils { } } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, char ch) { return indexOf(s, ch, 0); } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, char ch, int start) { Class<? extends CharSequence> c = s.getClass(); @@ -175,6 +178,7 @@ public class TextUtils { return indexOf(s, ch, start, s.length()); } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, char ch, int start, int end) { Class<? extends CharSequence> c = s.getClass(); @@ -212,10 +216,12 @@ public class TextUtils { return -1; } + @android.ravenwood.annotation.RavenwoodKeep public static int lastIndexOf(CharSequence s, char ch) { return lastIndexOf(s, ch, s.length() - 1); } + @android.ravenwood.annotation.RavenwoodKeep public static int lastIndexOf(CharSequence s, char ch, int last) { Class<? extends CharSequence> c = s.getClass(); @@ -225,6 +231,7 @@ public class TextUtils { return lastIndexOf(s, ch, 0, last); } + @android.ravenwood.annotation.RavenwoodKeep public static int lastIndexOf(CharSequence s, char ch, int start, int last) { if (last < 0) @@ -270,14 +277,17 @@ public class TextUtils { return -1; } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, CharSequence needle) { return indexOf(s, needle, 0, s.length()); } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, CharSequence needle, int start) { return indexOf(s, needle, start, s.length()); } + @android.ravenwood.annotation.RavenwoodKeep public static int indexOf(CharSequence s, CharSequence needle, int start, int end) { int nlen = needle.length(); @@ -305,6 +315,7 @@ public class TextUtils { return -1; } + @android.ravenwood.annotation.RavenwoodKeep public static boolean regionMatches(CharSequence one, int toffset, CharSequence two, int ooffset, int len) { @@ -337,6 +348,7 @@ public class TextUtils { * in that it does not preserve any style runs in the source sequence, * allowing a more efficient implementation. */ + @android.ravenwood.annotation.RavenwoodKeep public static String substring(CharSequence source, int start, int end) { if (source instanceof String) return ((String) source).substring(start, end); @@ -409,6 +421,7 @@ public class TextUtils { * calling object.toString(). If tokens is null, a NullPointerException will be thrown. If * tokens is an empty array, an empty string will be returned. */ + @android.ravenwood.annotation.RavenwoodKeep public static String join(@NonNull CharSequence delimiter, @NonNull Object[] tokens) { final int length = tokens.length; if (length == 0) { @@ -432,6 +445,7 @@ public class TextUtils { * calling object.toString(). If tokens is null, a NullPointerException will be thrown. If * tokens is empty, an empty string will be returned. */ + @android.ravenwood.annotation.RavenwoodKeep public static String join(@NonNull CharSequence delimiter, @NonNull Iterable tokens) { final Iterator<?> it = tokens.iterator(); if (!it.hasNext()) { @@ -464,9 +478,10 @@ public class TextUtils { * * @throws NullPointerException if expression or text is null */ + @android.ravenwood.annotation.RavenwoodKeep public static String[] split(String text, String expression) { if (text.length() == 0) { - return EMPTY_STRING_ARRAY; + return EmptyArray.STRING; } else { return text.split(expression, -1); } @@ -489,9 +504,10 @@ public class TextUtils { * * @throws NullPointerException if expression or text is null */ + @android.ravenwood.annotation.RavenwoodKeep public static String[] split(String text, Pattern pattern) { if (text.length() == 0) { - return EMPTY_STRING_ARRAY; + return EmptyArray.STRING; } else { return pattern.split(text, -1); } @@ -526,6 +542,7 @@ public class TextUtils { * be returned for the empty string after that delimeter. That is, splitting <tt>"a,b,"</tt> on * comma will return <tt>"a", "b"</tt>, not <tt>"a", "b", ""</tt>. */ + @android.ravenwood.annotation.RavenwoodKeepWholeClass public static class SimpleStringSplitter implements StringSplitter, Iterator<String> { private String mString; private char mDelimiter; @@ -589,26 +606,31 @@ public class TextUtils { * @param str the string to be examined * @return true if str is null or zero length */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isEmpty(@Nullable CharSequence str) { return str == null || str.length() == 0; } /** {@hide} */ + @android.ravenwood.annotation.RavenwoodKeep public static String nullIfEmpty(@Nullable String str) { return isEmpty(str) ? null : str; } /** {@hide} */ + @android.ravenwood.annotation.RavenwoodKeep public static String emptyIfNull(@Nullable String str) { return str == null ? "" : str; } /** {@hide} */ + @android.ravenwood.annotation.RavenwoodKeep public static String firstNotEmpty(@Nullable String a, @NonNull String b) { return !isEmpty(a) ? a : Preconditions.checkStringNotEmpty(b); } /** {@hide} */ + @android.ravenwood.annotation.RavenwoodKeep public static int length(@Nullable String s) { return s != null ? s.length() : 0; } @@ -617,6 +639,7 @@ public class TextUtils { * @return interned string if it's null. * @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static String safeIntern(String s) { return (s != null) ? s.intern() : null; } @@ -626,6 +649,7 @@ public class TextUtils { * spaces and ASCII control characters were trimmed from the start and end, * as by {@link String#trim}. */ + @android.ravenwood.annotation.RavenwoodKeep public static int getTrimmedLength(CharSequence s) { int len = s.length(); @@ -650,6 +674,7 @@ public class TextUtils { * @param b second CharSequence to check * @return true if a and b are equal */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean equals(CharSequence a, CharSequence b) { if (a == b) return true; int length; @@ -1679,6 +1704,7 @@ public class TextUtils { return true; } + @android.ravenwood.annotation.RavenwoodReplace /* package */ static char[] obtain(int len) { char[] buf; @@ -1693,6 +1719,11 @@ public class TextUtils { return buf; } + /* package */ static char[] obtain$ravenwood(int len) { + return new char[len]; + } + + @android.ravenwood.annotation.RavenwoodReplace /* package */ static void recycle(char[] temp) { if (temp.length > 1000) return; @@ -1702,11 +1733,16 @@ public class TextUtils { } } + /* package */ static void recycle$ravenwood(char[] temp) { + // Handled by typical GC + } + /** * Html-encode the string. * @param s the string to be encoded * @return the encoded string */ + @android.ravenwood.annotation.RavenwoodKeep public static String htmlEncode(String s) { StringBuilder sb = new StringBuilder(); char c; @@ -1793,6 +1829,7 @@ public class TextUtils { /** * Returns whether the given CharSequence contains any printable characters. */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isGraphic(CharSequence str) { final int len = str.length(); for (int cp, i=0; i<len; i+=Character.charCount(cp)) { @@ -1819,6 +1856,7 @@ public class TextUtils { * @deprecated Use {@link #isGraphic(CharSequence)} instead. */ @Deprecated + @android.ravenwood.annotation.RavenwoodKeep public static boolean isGraphic(char c) { int gc = Character.getType(c); return gc != Character.CONTROL @@ -1833,6 +1871,7 @@ public class TextUtils { /** * Returns whether the given CharSequence contains only digits. */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isDigitsOnly(CharSequence str) { final int len = str.length(); for (int cp, i = 0; i < len; i += Character.charCount(cp)) { @@ -1847,6 +1886,7 @@ public class TextUtils { /** * @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isPrintableAscii(final char c) { final int asciiFirst = 0x20; final int asciiLast = 0x7E; // included @@ -1857,6 +1897,7 @@ public class TextUtils { * @hide */ @UnsupportedAppUsage + @android.ravenwood.annotation.RavenwoodKeep public static boolean isPrintableAsciiOnly(final CharSequence str) { final int len = str.length(); for (int i = 0; i < len; i++) { @@ -1908,6 +1949,7 @@ public class TextUtils { * {@link #CAP_MODE_CHARACTERS}, {@link #CAP_MODE_WORDS}, and * {@link #CAP_MODE_SENTENCES}. */ + @android.ravenwood.annotation.RavenwoodKeep public static int getCapsMode(CharSequence cs, int off, int reqModes) { if (off < 0) { return 0; @@ -2153,6 +2195,7 @@ public class TextUtils { * match the supported grammar described above. * @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static @NonNull String formatSimple(@NonNull String format, Object... args) { final StringBuilder sb = new StringBuilder(format); int j = 0; @@ -2342,6 +2385,7 @@ public class TextUtils { } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isNewline(int codePoint) { int type = Character.getType(codePoint); return type == Character.PARAGRAPH_SEPARATOR || type == Character.LINE_SEPARATOR @@ -2349,16 +2393,19 @@ public class TextUtils { } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isWhitespace(int codePoint) { return Character.isWhitespace(codePoint) || codePoint == NBSP_CODE_POINT; } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isWhitespaceExceptNewline(int codePoint) { return isWhitespace(codePoint) && !isNewline(codePoint); } /** @hide */ + @android.ravenwood.annotation.RavenwoodKeep public static boolean isPunctuation(int codePoint) { int type = Character.getType(codePoint); return type == Character.CONNECTOR_PUNCTUATION @@ -2608,6 +2655,4 @@ public class TextUtils { private static Object sLock = new Object(); private static char[] sTemp = null; - - private static String[] EMPTY_STRING_ARRAY = new String[]{}; } diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig index 43c38f319713..a1885ae616e1 100644 --- a/core/java/android/text/flags/flags.aconfig +++ b/core/java/android/text/flags/flags.aconfig @@ -75,3 +75,10 @@ flag { description: "A feature flag that implements line break word style auto." bug: "280005585" } + +flag { + name: "inter_character_justification" + namespace: "text" + description: "A feature flag that implement inter character justification." + bug: "283193133" +} diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index d6535d477e5d..dbacca5def51 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -59,8 +59,15 @@ interface IWindowSession { int addToDisplayWithoutInputChannel(IWindow window, in WindowManager.LayoutParams attrs, in int viewVisibility, in int layerStackId, out InsetsState insetsState, out Rect attachedFrame, out float[] sizeCompatScale); - @UnsupportedAppUsage - void remove(IWindow window); + + /** + * Removes a clientToken from WMS, which includes unlinking the input channel. + * + * @param clientToken The token that should be removed. This will normally be the IWindow token + * for a standard window. It can also be the generic clientToken that was used when calling + * grantInputChannel + */ + void remove(IBinder clientToken); /** * Change the parameters of a window. You supply the diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index 1acc384b18da..cabab6c80bf5 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -49,8 +49,9 @@ public class InsetsSource implements Parcelable { /** The insets source ID of IME */ public static final int ID_IME = createId(null, 0, ime()); + /** The insets source ID of the IME caption bar ("fake" IME navigation bar). */ - static final int ID_IME_CAPTION_BAR = + public static final int ID_IME_CAPTION_BAR = InsetsSource.createId(null /* owner */, 1 /* index */, captionBar()); /** diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 451a71b71e3f..8befe8a2be85 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -436,13 +436,16 @@ public final class SurfaceControl implements Parcelable { // Jank due to unknown reasons. public static final int UNKNOWN = 0x80; - public JankData(long frameVsyncId, @JankType int jankType) { + public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs) { this.frameVsyncId = frameVsyncId; this.jankType = jankType; + this.frameIntervalNs = frameIntervalNs; + } public final long frameVsyncId; public final @JankType int jankType; + public final long frameIntervalNs; } /** @@ -3280,7 +3283,8 @@ public final class SurfaceControl implements Parcelable { "setCrop", this, sc, "crop=" + crop); } if (crop != null) { - Preconditions.checkArgument(crop.isValid(), "Crop isn't valid."); + Preconditions.checkArgument(crop.isValid(), "Crop " + crop + + " isn't valid"); nativeSetWindowCrop(mNativeObject, sc.mNativeObject, crop.left, crop.top, crop.right, crop.bottom); } else { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 0ae14a2fdb30..a44a95a1677f 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -1523,15 +1523,24 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall if (mSurfaceControl == null) return; mRTLastReportedPosition.set(left, top, right, bottom); + final float postScaleX = mRTLastReportedPosition.width() + / (float) mRtSurfaceWidth; + final float postScaleY = mRTLastReportedPosition.height() + / (float) mRtSurfaceHeight; onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl, mRTLastReportedPosition.left /*positionLeft*/, mRTLastReportedPosition.top /*positionTop*/, - mRTLastReportedPosition.width() - / (float) mRtSurfaceWidth /*postScaleX*/, - mRTLastReportedPosition.height() - / (float) mRtSurfaceHeight /*postScaleY*/); - - mRTLastSetCrop.set(clipLeft, clipTop, clipRight, clipBottom); + postScaleX, postScaleY); + + mRTLastSetCrop.set((int) (clipLeft / postScaleX), (int) (clipTop / postScaleY), + (int) Math.ceil(clipRight / postScaleX), + (int) Math.ceil(clipBottom / postScaleY)); + if (DEBUG_POSITION) { + Log.d(TAG, String.format("Setting layer crop = [%d, %d, %d, %d] " + + "from scale %f, %f", mRTLastSetCrop.left, + mRTLastSetCrop.top, mRTLastSetCrop.right, mRTLastSetCrop.bottom, + postScaleX, postScaleY)); + } mPositionChangedTransaction.setCrop(mSurfaceControl, mRTLastSetCrop); if (mRTLastSetCrop.isEmpty()) { mPositionChangedTransaction.hide(mSurfaceControl); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 5ff028c51ce2..7b456007e4ae 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -5879,7 +5879,7 @@ public final class ViewRootImpl implements ViewParent, mInputQueue = null; } try { - mWindowSession.remove(mWindow); + mWindowSession.remove(mWindow.asBinder()); } catch (RemoteException e) { } // Dispose receiver would dispose client InputChannel, too. That could send out a socket diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index da310780a813..d817e6f51f55 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -276,11 +276,11 @@ public class WindowlessWindowManager implements IWindowSession { } @Override - public void remove(android.view.IWindow window) throws RemoteException { - mRealWm.remove(window); + public void remove(IBinder clientToken) throws RemoteException { + mRealWm.remove(clientToken); State state; synchronized (this) { - state = mStateForWindow.remove(window.asBinder()); + state = mStateForWindow.remove(clientToken); } if (state == null) { throw new IllegalArgumentException( diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java index b220c4d0c763..07ae1345a688 100644 --- a/core/java/android/view/accessibility/AccessibilityManager.java +++ b/core/java/android/view/accessibility/AccessibilityManager.java @@ -17,6 +17,7 @@ package android.view.accessibility; import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; import android.Manifest; import android.accessibilityservice.AccessibilityService; @@ -25,6 +26,7 @@ import android.accessibilityservice.AccessibilityServiceInfo.FeedbackType; import android.accessibilityservice.AccessibilityShortcutInfo; import android.annotation.CallbackExecutor; import android.annotation.ColorInt; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -2042,6 +2044,9 @@ public final class AccessibilityManager { * @return {@code true} if flash notification works properly. * @hide */ + @FlaggedApi(Flags.FLAG_FLASH_NOTIFICATION_SYSTEM_API) + @TestApi + @SystemApi(client = MODULE_LIBRARIES) public boolean startFlashNotificationSequence(@NonNull Context context, @FlashNotificationReason int reason) { final IAccessibilityManager service; @@ -2071,6 +2076,9 @@ public final class AccessibilityManager { * @return {@code true} if flash notification stops properly. * @hide */ + @FlaggedApi(Flags.FLAG_FLASH_NOTIFICATION_SYSTEM_API) + @TestApi + @SystemApi(client = MODULE_LIBRARIES) public boolean stopFlashNotificationSequence(@NonNull Context context) { final IAccessibilityManager service; synchronized (mLock) { diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig index 5296b9992542..950fa4b1d711 100644 --- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig +++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig @@ -25,6 +25,13 @@ flag { flag { namespace: "accessibility" + name: "flash_notification_system_api" + description: "Makes flash notification APIs as system APIs for calling from mainline module" + bug: "282821643" +} + +flag { + namespace: "accessibility" name: "force_invert_color" description: "Enable force force-dark for smart inversion and dark theme everywhere" bug: "282821643" diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java index 95e9e861bea2..befb0023ebe6 100644 --- a/core/java/android/window/ScreenCapture.java +++ b/core/java/android/window/ScreenCapture.java @@ -528,14 +528,12 @@ public class ScreenCapture { private final IBinder mDisplayToken; private final int mWidth; private final int mHeight; - private final boolean mUseIdentityTransform; private DisplayCaptureArgs(Builder builder) { super(builder); mDisplayToken = builder.mDisplayToken; mWidth = builder.mWidth; mHeight = builder.mHeight; - mUseIdentityTransform = builder.mUseIdentityTransform; } /** @@ -545,7 +543,6 @@ public class ScreenCapture { private IBinder mDisplayToken; private int mWidth; private int mHeight; - private boolean mUseIdentityTransform; /** * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder @@ -586,17 +583,6 @@ public class ScreenCapture { return this; } - /** - * Replace the rotation transform of the display with the identity transformation while - * taking the screenshot. This ensures the screenshot is taken in the ROTATION_0 - * orientation. Set this value to false if the screenshot should be taken in the - * current screen orientation. - */ - public Builder setUseIdentityTransform(boolean useIdentityTransform) { - mUseIdentityTransform = useIdentityTransform; - return this; - } - @Override Builder getThis() { return this; diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig index 68eddff19922..42a1f1e58967 100644 --- a/core/java/android/window/flags/window_surfaces.aconfig +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -32,3 +32,10 @@ flag { description: "Enable public API for Window Surfaces" bug: "287076178" } + +flag { + namespace: "window_surfaces" + name: "remove_capture_display" + description: "Remove uses of ScreenCapture#captureDisplay" + bug: "293445881" +}
\ No newline at end of file diff --git a/core/java/com/android/internal/jank/DisplayRefreshRate.java b/core/java/com/android/internal/jank/DisplayRefreshRate.java new file mode 100644 index 000000000000..354c4132dcd1 --- /dev/null +++ b/core/java/com/android/internal/jank/DisplayRefreshRate.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.jank; + +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__UNKNOWN_REFRESH_RATE; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__VARIABLE_REFRESH_RATE; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_30_HZ; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_60_HZ; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_90_HZ; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_120_HZ; +import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_240_HZ; + +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Display refresh rate related functionality. + * @hide + */ +public class DisplayRefreshRate { + public static final int UNKNOWN_REFRESH_RATE = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__UNKNOWN_REFRESH_RATE; + public static final int VARIABLE_REFRESH_RATE = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__VARIABLE_REFRESH_RATE; + public static final int REFRESH_RATE_30_HZ = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_30_HZ; + public static final int REFRESH_RATE_60_HZ = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_60_HZ; + public static final int REFRESH_RATE_90_HZ = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_90_HZ; + public static final int REFRESH_RATE_120_HZ = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_120_HZ; + public static final int REFRESH_RATE_240_HZ = + UIINTERACTION_FRAME_INFO_REPORTED__DISPLAY_REFRESH_RATE__RR_240_HZ; + + /** @hide */ + @IntDef({ + UNKNOWN_REFRESH_RATE, + VARIABLE_REFRESH_RATE, + REFRESH_RATE_30_HZ, + REFRESH_RATE_60_HZ, + REFRESH_RATE_90_HZ, + REFRESH_RATE_120_HZ, + REFRESH_RATE_240_HZ, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface RefreshRate { + } + + private DisplayRefreshRate() { + } + + /** + * Computes the display refresh rate based off the frame interval. + */ + @RefreshRate + public static int getRefreshRate(long frameIntervalNs) { + long rate = Math.round(1e9 / frameIntervalNs); + if (rate < 50) { + return REFRESH_RATE_30_HZ; + } else if (rate < 80) { + return REFRESH_RATE_60_HZ; + } else if (rate < 110) { + return REFRESH_RATE_90_HZ; + } else if (rate < 180) { + return REFRESH_RATE_120_HZ; + } else { + return REFRESH_RATE_240_HZ; + } + } +} diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java index 506f19f7719a..c83452d88290 100644 --- a/core/java/com/android/internal/jank/FrameTracker.java +++ b/core/java/com/android/internal/jank/FrameTracker.java @@ -24,6 +24,8 @@ import static android.view.SurfaceControl.JankData.JANK_SURFACEFLINGER_GPU_DEADL import static android.view.SurfaceControl.JankData.PREDICTION_ERROR; import static android.view.SurfaceControl.JankData.SURFACE_FLINGER_SCHEDULING; +import static com.android.internal.jank.DisplayRefreshRate.UNKNOWN_REFRESH_RATE; +import static com.android.internal.jank.DisplayRefreshRate.VARIABLE_REFRESH_RATE; import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_CANCEL; import static com.android.internal.jank.InteractionJankMonitor.ACTION_SESSION_END; import static com.android.internal.jank.InteractionJankMonitor.EXECUTOR_TASK_TIMEOUT; @@ -49,6 +51,7 @@ import android.view.ViewRootImpl; import android.view.WindowCallbacks; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.jank.DisplayRefreshRate.RefreshRate; import com.android.internal.jank.InteractionJankMonitor.Configuration; import com.android.internal.jank.InteractionJankMonitor.Session; import com.android.internal.util.FrameworkStatsLog; @@ -132,26 +135,30 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener boolean hwuiCallbackFired; boolean surfaceControlCallbackFired; @JankType int jankType; + @RefreshRate int refreshRate; static JankInfo createFromHwuiCallback(long frameVsyncId, long totalDurationNanos, boolean isFirstFrame) { - return new JankInfo(frameVsyncId, true, false, JANK_NONE, totalDurationNanos, - isFirstFrame); + return new JankInfo(frameVsyncId, true, false, JANK_NONE, UNKNOWN_REFRESH_RATE, + totalDurationNanos, isFirstFrame); } static JankInfo createFromSurfaceControlCallback(long frameVsyncId, - @JankType int jankType) { - return new JankInfo(frameVsyncId, false, true, jankType, 0, false /* isFirstFrame */); + @JankType int jankType, @RefreshRate int refreshRate) { + return new JankInfo( + frameVsyncId, false, true, jankType, refreshRate, 0, false /* isFirstFrame */); } private JankInfo(long frameVsyncId, boolean hwuiCallbackFired, boolean surfaceControlCallbackFired, @JankType int jankType, + @RefreshRate int refreshRate, long totalDurationNanos, boolean isFirstFrame) { this.frameVsyncId = frameVsyncId; this.hwuiCallbackFired = hwuiCallbackFired; this.surfaceControlCallbackFired = surfaceControlCallbackFired; - this.totalDurationNanos = totalDurationNanos; this.jankType = jankType; + this.refreshRate = refreshRate; + this.totalDurationNanos = totalDurationNanos; this.isFirstFrame = isFirstFrame; } @@ -468,14 +475,16 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener if (!isInRange(jankStat.frameVsyncId)) { continue; } + int refreshRate = DisplayRefreshRate.getRefreshRate(jankStat.frameIntervalNs); JankInfo info = findJankInfo(jankStat.frameVsyncId); if (info != null) { info.surfaceControlCallbackFired = true; info.jankType = jankStat.jankType; + info.refreshRate = refreshRate; } else { mJankInfos.put((int) jankStat.frameVsyncId, JankInfo.createFromSurfaceControlCallback( - jankStat.frameVsyncId, jankStat.jankType)); + jankStat.frameVsyncId, jankStat.jankType, refreshRate)); } } processJankInfos(); @@ -592,6 +601,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener int missedSfFramesCount = 0; int maxSuccessiveMissedFramesCount = 0; int successiveMissedFramesCount = 0; + @RefreshRate int refreshRate = UNKNOWN_REFRESH_RATE; for (int i = 0; i < mJankInfos.size(); i++) { JankInfo info = mJankInfos.valueAt(i); @@ -627,6 +637,10 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener maxSuccessiveMissedFramesCount, successiveMissedFramesCount); successiveMissedFramesCount = 0; } + if (info.refreshRate != UNKNOWN_REFRESH_RATE && info.refreshRate != refreshRate) { + refreshRate = (refreshRate == UNKNOWN_REFRESH_RATE) + ? info.refreshRate : VARIABLE_REFRESH_RATE; + } // TODO (b/174755489): Early latch currently gets fired way too often, so we have // to ignore it for now. if (!mSurfaceOnly && !info.hwuiCallbackFired) { @@ -669,6 +683,7 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener mStatsLog.write( FrameworkStatsLog.UI_INTERACTION_FRAME_INFO_REPORTED, mDisplayId, + refreshRate, mSession.getStatsdInteractionType(), totalFramesCount, missedFramesCount, @@ -866,10 +881,10 @@ public class FrameTracker extends SurfaceControl.OnJankDataListener } /** {@see FrameworkStatsLog#write) */ - public void write(int code, int displayId, + public void write(int code, int displayId, @RefreshRate int refreshRate, int arg1, long arg2, long arg3, long arg4, long arg5, long arg6, long arg7) { FrameworkStatsLog.write(code, arg1, arg2, arg3, arg4, arg5, arg6, arg7, - mDisplayResolutionTracker.getResolution(displayId)); + mDisplayResolutionTracker.getResolution(displayId), refreshRate); } } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 0947ec178c77..f62094d231ef 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -618,4 +618,14 @@ public final class VpnProfile implements Cloneable, Parcelable { public int describeContents() { return 0; } + + @Override + public VpnProfile clone() { + try { + return (VpnProfile) super.clone(); + } catch (CloneNotSupportedException e) { + Log.wtf(TAG, e); + return null; + } + } } diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index 70514c30d90d..01c91bae72cd 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -337,6 +337,12 @@ public class ProcessCpuTracker { @UnsupportedAppUsage public void update() { + synchronized (this) { + updateLocked(); + } + } + + private void updateLocked() { if (DEBUG) Slog.v(TAG, "Update: " + this); final long nowUptime = SystemClock.uptimeMillis(); diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 3977666627b7..fc60f065a965 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -90,7 +90,7 @@ interface IStatusBarService void onNotificationSettingsViewed(String key); void onNotificationBubbleChanged(String key, boolean isBubble, int flags); void onBubbleMetadataFlagChanged(String key, int flags); - void hideCurrentInputMethodForBubbles(); + void hideCurrentInputMethodForBubbles(int displayId); void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName); oneway void clearInlineReplyUriPermissions(String key); void onNotificationFeedbackReceived(String key, in Bundle feedback); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index a800e6ea60e4..db42246ca76c 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -1951,8 +1951,9 @@ public: jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(), gJankDataClassInfo.clazz, nullptr); for (size_t i = 0; i < jankData.size(); i++) { - jobject jJankData = env->NewObject(gJankDataClassInfo.clazz, - gJankDataClassInfo.ctor, jankData[i].frameVsyncId, jankData[i].jankType); + jobject jJankData = env->NewObject(gJankDataClassInfo.clazz, gJankDataClassInfo.ctor, + jankData[i].frameVsyncId, jankData[i].jankType, + jankData[i].frameIntervalNs); env->SetObjectArrayElement(jJankDataArray, i, jJankData); env->DeleteLocalRef(jJankData); } @@ -2523,8 +2524,7 @@ int register_android_view_SurfaceControl(JNIEnv* env) jclass jankDataClazz = FindClassOrDie(env, "android/view/SurfaceControl$JankData"); gJankDataClassInfo.clazz = MakeGlobalRefOrDie(env, jankDataClazz); - gJankDataClassInfo.ctor = - GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JI)V"); + gJankDataClassInfo.ctor = GetMethodIDOrDie(env, gJankDataClassInfo.clazz, "<init>", "(JIJ)V"); jclass onJankDataListenerClazz = FindClassOrDie(env, "android/view/SurfaceControl$OnJankDataListener"); gJankDataListenerClassInfo.clazz = MakeGlobalRefOrDie(env, onJankDataListenerClazz); diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp index bdf7eaa8aace..6e903b3ab56d 100644 --- a/core/jni/android_window_ScreenCapture.cpp +++ b/core/jni/android_window_ScreenCapture.cpp @@ -53,7 +53,6 @@ static struct { jfieldID displayToken; jfieldID width; jfieldID height; - jfieldID useIdentityTransform; } gDisplayCaptureArgsClassInfo; static struct { @@ -194,9 +193,6 @@ static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width); captureArgs.height = env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height); - captureArgs.useIdentityTransform = - env->GetBooleanField(displayCaptureArgsObject, - gDisplayCaptureArgsClassInfo.useIdentityTransform); return captureArgs; } @@ -325,8 +321,6 @@ int register_android_window_ScreenCapture(JNIEnv* env) { GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I"); gDisplayCaptureArgsClassInfo.height = GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I"); - gDisplayCaptureArgsClassInfo.useIdentityTransform = - GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z"); jclass layerCaptureArgsClazz = FindClassOrDie(env, "android/window/ScreenCapture$LayerCaptureArgs"); diff --git a/core/res/Android.bp b/core/res/Android.bp index 4e686b7ad80c..34c404520a2b 100644 --- a/core/res/Android.bp +++ b/core/res/Android.bp @@ -152,6 +152,8 @@ android_app { "simulated_device_launcher", ], }, + + generate_product_characteristics_rro: true, } java_genrule { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 76ae3e0b516b..926e0fa2f844 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2372,7 +2372,7 @@ them from running without explicit user action. --> <permission android:name="android.permission.QUARANTINE_APPS" - android:protectionLevel="internal|verifier" /> + android:protectionLevel="signature|verifier" /> <!-- Allows applications to discover and pair bluetooth devices. <p>Protection level: normal diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 50372395a1dc..f9ab7dd283c9 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Dit kan jou interaksies met \'n app of \'n hardewaresensor naspoor en namens jou met apps interaksie hê."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Laat toe"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Weier"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tik op \'n kenmerk om dit te begin gebruik:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Kies kenmerke om saam met die toeganklikheidknoppie te gebruik"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Kies kenmerke om saam met die volumesleutelkortpad te gebruik"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Naweek"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Geleentheid"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Slaap"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> demp sekere klanke"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Daar is \'n interne probleem met jou toestel. Kontak jou vervaardiger vir besonderhede."</string> @@ -2336,6 +2344,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoon is geblokkeer"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kan nie na skerm weerspieël nie"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gebruik ’n ander kabel en probeer weer"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"Jou toestel is te warm en kan nie na die skerm weerspieël totdat dit afgekoel het nie"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel steun dalk nie skerms nie"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Jou USB-C-kabel koppel dalk nie behoorlik aan skerms nie"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 9a8bb6233172..5ac3225274d4 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ከመተግበሪያ ጋር ወይም የሃርድዌር ዳሳሽ ጋር እርስዎ ያልዎትን መስተጋብሮች ዱካ መከታተል እና በእርስዎ ምትክ ከመተግበሪያዎች ጋር መስተጋብር መፈጸም ይችላል።"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ፍቀድ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ከልክል"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"በድምጽ ቁልፍ አቋራጭ የሚጠቀሙባቸው ባሕሪያት ይምረጡ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"የሳምንት እረፍት ቀናት"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ክስተት"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"መተኛት"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> አንዳንድ ድምጾችን እየዘጋ ነው"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ፣ የፋብሪካ ውሂብ ዳግም እስኪያስጀምሩት ድረስ ላይረጋጋ ይችላል።"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ። ዝርዝሮችን ለማግኘት አምራችዎን ያነጋግሩ።"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ማይክሮፎን ታግዷል"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ወደ ማሳያ ማንጸባረቅ አልተቻለም"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"የተለየ ገመድ ይጠቀሙ እና እንደገና ይሞክሩ"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ገመድ ማሳያዎችን ላይደግፍ ይችላል"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"የእርስዎ USB-C ገመድ ከማሳያዎች ጋር በትክክል ላይገናኝ ይችላል"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index f6d7c647c84f..537beece8cfa 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1694,7 +1694,7 @@ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"إزالة"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string> <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="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">"عند تفعيل الاختصار، يؤدي الضغط على زرّي التحكّم في مستوى الصوت معًا لمدة 3 ثوانٍ إلى تفعيل إحدى ميزات إمكانية الوصول."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"هل تريد تفعيل الاختصار لميزات إمكانية الوصول؟"</string> @@ -1714,6 +1714,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"قد يؤدي ذلك إلى السماح للميزة بتتبّع تفاعلاتك مع تطبيق أو جهاز استشعار والتفاعل مع التطبيقات نيابةً عنك."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"سماح"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"رفض"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"اختيار الميزات التي تريد استخدامها مع اختصار مفتاح التحكّم في مستوى الصوت"</string> @@ -1908,6 +1912,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"نهاية الأسبوع"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"حدث"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"النوم"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"يعمل <xliff:g id="THIRD_PARTY">%1$s</xliff:g> على كتم بعض الأصوات."</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط على الإعدادات الأصلية."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"حدثت مشكلة داخلية في جهازك. يمكنك الاتصال بالمصنِّع للحصول على تفاصيل."</string> @@ -2340,6 +2348,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"تم حظر الميكروفون."</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"يتعذّر إجراء نسخ مطابق لمحتوى جهازك إلى الشاشة"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"يُرجى استخدام كابل آخر وإعادة المحاولة."</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"قد لا يتوافق الكابل مع الشاشات"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"قد لا يتم توصيل الكابل المزوَّد بمنفذ USB-C بالشاشات بشكل صحيح."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 517ae9aabbf8..a5d2ee415a3f 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ই আপুনি কোনো এপ্ বা হার্ডৱেৰ ছেন্সৰৰ সৈতে কৰা ভাব-বিনিময় আৰু আপোনাৰ হৈ অন্য কোনো লোকে এপৰ সৈতে কৰা ভাব-বিনিময় ট্ৰেক কৰিব পাৰে।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"অনুমতি দিয়ক"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"অস্বীকাৰ কৰক"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ভলিউম কীৰ শ্বৰ্টকাটটোৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ সুবিধাসমূহ বাছনি কৰক"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহ অন্ত"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"কার্যক্ৰম"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"নিদ্ৰাৰত"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>এ কিছুমান ধ্বনি মিউট কৰি আছে"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে আৰু আপুনি ফেক্টৰী ডেটা ৰিছেট নকৰালৈকে ই সুস্থিৰভাৱে কাম নকৰিব পাৰে।"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে। সবিশেষ জানিবৰ বাবে আপোনাৰ ডিভাইচ নির্মাতাৰ সৈতে যোগাযোগ কৰক।"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"মাইক্ৰ’ফ’নটো অৱৰোধ কৰি থোৱা আছে"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"সংযুক্ত ডিছপ্লে’ উপলব্ধ নহয়"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"অন্য এডাল কে’বল ব্যৱহাৰ কৰি পুনৰ চেষ্টা কৰক"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"কে’বলে ডিছপ্লে’ সমৰ্থন নকৰিবও পাৰে"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"আপোনাৰ USB-C কে’বল ডিছপ্লে’ৰ সৈতে সঠিকভাৱে সংযোগ নহ’বও পাৰে"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index c0115550c35a..87e1c9f28fff 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Tətbiq və sensorlarla əlaqələrinizi izləyib tətbiqlərə adınızdan əmrlər verə bilər."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"İcazə verin"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"İmtina edin"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Funksiyanı istifadə etmək üçün onun üzərinə toxunun:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Xüsusi imkanlar düyməsinin köməyilə işə salınacaq funksiyaları seçin"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Səs səviyyəsi düyməsinin qısayolu ilə istifadə edəcəyiniz funksiyaları seçin"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Həftə sonu"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tədbir"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Yuxu vaxtı"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bəzi səsləri səssiz rejimə salır"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızın daxili problemi var və istehsalçı sıfırlanması olmayana qədər qeyri-stabil ola bilər."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Cihazınızın daxili problemi var. Əlavə məlumat üçün istehsalçı ilə əlaqə saxlayın."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon blok edilib"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Displeydə əks etdirmək olmur"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Başqa kabel istifadə edin və yenidən cəhd edin"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel displeyləri dəstəkləməyə bilər"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C kabeli displeylərə düzgün qoşulmaya bilər"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"İkili ekran"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 48b5c02c6286..06d73eedbaa9 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može da prati interakcije sa aplikacijom ili senzorom hardvera i koristi aplikacije umesto vas."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dozvoli"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite neku funkciju da biste počeli da je koristite:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti sa dugmetom Pristupačnost"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije za prečicu tasterom jačine zvuka"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Došlo je do internog problema u vezi sa uređajem. Potražite detalje od proizvođača."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Preslikavanje na ekran nije moguće"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Upotrebite drugi kabl i probajte ponovo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabl ne podržava ekrane"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C kabl se ne povezuje pravilno sa ekranima"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 12effa0c6485..7ff6838951fb 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Гэта функцыя можа адсочваць вашы ўзаемадзеянні з праграмай ці датчыкам апаратнага забеспячэння і ўзаемадзейнічаць з праграмамі ад вашага імя."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дазволіць"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Адмовіць"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Выберыце функцыі для выкарыстання з клавішай гучнасці"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выхадныя"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Падзея"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Рэжым сну"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> выключае некаторыя гукі"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"На вашай прыладзе ўзнікла ўнутраная праблема, і яна можа працаваць нестабільна, пакуль вы не зробіце скід да заводскіх налад."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"На вашай прыладзе ўзнікла ўнутраная праблема. Для атрымання дадатковай інфармацыі звярніцеся да вытворцы."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Мікрафон заблакіраваны"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Не ўдалося прадубліраваць змесціва на дысплэі"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Паспрабуйце скарыстаць іншы кабель"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Магчыма, кабель несумяшчальны з дысплэямі"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Магчыма, кабель USB-C не падыходзіць да дысплэяў"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index d18e4bc5f00e..304c2a0d8fae 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Услугата може да проследява взаимодействията ви с дадено приложение или хардуерен сензор, както и да взаимодейства с приложенията от ваше име."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Разреш."</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Отказ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Избиране на функции, които да използвате с прекия път чрез бутона за силата на звука"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Събота и неделя"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Събитие"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Време за сън"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> заглушава някои звуци"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Възникна вътрешен проблем с устройството ви. То може да е нестабилно, докато не възстановите фабричните настройки."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Възникна вътрешен проблем с устройството ви. За подробности се свържете с производителя."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофонът е блокиран"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Не може да се копира огледално на дисплея"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Използвайте друг кабел и опитайте отново"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабелът не поддържа дисплеи"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C кабелът ви може да не се свързва правилно с дисплеи"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 859f37d026aa..1c6fa8da2bb4 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"এটি কোনও একটি অ্যাপের সাথে অথবা হার্ডওয়্যার সেন্সরের সাথে আপনার ইন্টার্যাকশন ট্র্যাক করতে এবং আপনার হয়ে বিভিন্ন অ্যাপের সাথে ইন্টার্যাক্ট করতে পারে।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"অনুমতি দিন"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"খারিজ করুন"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ভলিউম কী শর্টকাটের সাহায্যে আপনি যেসব ফিচার ব্যবহার করতে চান সেগুলি বেছে নিন"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহান্ত"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ইভেন্ট"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ঘুমানোর সময়"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> কিছু সাউন্ডকে মিউট করে দিচ্ছে"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে, এবং আপনি যতক্ষণ না পর্যন্ত এটিকে ফ্যাক্টরি ডেটা রিসেট করছেন ততক্ষণ এটি ঠিকভাবে কাজ নাও করতে পারে৷"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে৷ বিস্তারিত জানার জন্য প্রস্তুতকারকের সাথে যোগাযোগ করুন৷"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"মাইক্রোফোন ব্লক করা হয়েছে"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ডিসপ্লে মিরর করা যাচ্ছে না"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"অন্য কোনও কেবল ব্যবহার করে আবার চেষ্টা করুন"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"কেবল, ডিসপ্লের সাথে কাজ নাও করতে পারে"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"আপনার USB-C কেবল, ডিসপ্লেতে সঠিকভাবে কানেক্ট নাও হতে পারে"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 20f1d68a2fa0..c3f431a32ea5 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može pratiti vaše interakcije s aplikacijom ili hardverskim senzorom te ostvariti interakciju s aplikacijama umjesto vas."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dozvoli"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite funkciju da je počnete koristiti:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odaberite funkcije koje ćete koristiti s dugmetom Pristupačnost"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odaberite funkcije koje ćete koristiti pomoću prečice tipke za jačinu zvuka"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Postoji problem u vašem uređaju i može biti nestabilan dok ga ne vratite na fabričke postavke."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Postoji problem u vašem uređaju. Za više informacija obratite se proizvođaču."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nije moguće preslikati na ekran"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Upotrijebite drugi kabl i pokušajte ponovo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabl možda neće podržavati ekrane"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C kabl se možda neće pravilno povezati s ekranima"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 18e5abeb5eb1..fbbd2daf5dec 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pot fer un seguiment de les teves interaccions amb una aplicació o un sensor de maquinari, i interaccionar amb aplicacions en nom teu."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permet"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Denega"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toca una funció per començar a utilitzar-la:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Tria les funcions que vols utilitzar amb el botó d\'accessibilitat"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Tria les funcions que vols utilitzar amb la drecera per a tecles de volum"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cap de setmana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Esdeveniment"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Mentre dormo"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> està silenciant alguns sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"S\'ha produït un error intern al dispositiu. Contacta amb el fabricant del dispositiu per obtenir més informació."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"El micròfon està bloquejat"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"No es pot projectar a la pantalla"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Utilitza un altre cable i torna-ho a provar"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"És possible que el cable no sigui compatible amb pantalles"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"És possible que el teu cable USB-C no es connecti correctament a les pantalles"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 29e00fa4d212..959b7bc0ceb7 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Služba může sledovat vaše interakce s aplikací nebo hardwarovým senzorem a komunikovat s aplikacemi namísto vás."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Povolit"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zakázat"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Chcete-li některou funkci začít používat, klepněte na ni:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Vyberte funkce, které budete používat s tlačítkem přístupnosti"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Vyberte funkce, které budete používat se zkratkou tlačítka hlasitosti"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Událost"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spánek"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypíná určité zvuky"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"V zařízení došlo k internímu problému. Další informace vám sdělí výrobce."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je zablokován"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nelze zrcadlit na displej"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Použijte jiný kabel a zkuste to znovu"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel možná nepodporuje displeje"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Váš kabel USB-C se možná nedokáže správně připojit k displejům"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 87703cdb2fd9..751831a329c0 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan spore dine interaktioner med en app eller en hardwaresensor og interagere med apps på dine vegne."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Tillad"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Afvis"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tryk på en funktion for at bruge den:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Vælg, hvilke funktioner du vil bruge med knappen til hjælpefunktioner"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Vælg de funktioner, du vil bruge via lydstyrkeknapperne"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Begivenhed"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sover"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår nogle lyde fra"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Der er et internt problem med enheden. Kontakt producenten for at få yderligere oplysninger."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen er blokeret"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Det er ikke muligt at spejle til skærmen"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Brug et andet kabel, og prøv igen"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kablet understøtter muligvis ikke skærme"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Dit USB-C-kabel kan muligvis ikke sluttes korrekt til skærmene"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index f8eb0a0655d7..56816fbfd346 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Die Funktion kann deine Interaktionen mit einer App oder einem Hardwaresensor verfolgen und in deinem Namen mit Apps interagieren."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Zulassen"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Ablehnen"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Zum Auswählen der gewünschten Funktion tippen:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Funktionen auswählen, die du mit der Schaltfläche \"Bedienungshilfen\" verwenden möchtest"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funktionen für Verknüpfung mit Lautstärketaste auswählen"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wochenende"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Termin"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Schlafen"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"Einige Töne werden von <xliff:g id="THIRD_PARTY">%1$s</xliff:g> stummgeschaltet"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Es liegt ein internes Problem mit deinem Gerät vor. Bitte wende dich diesbezüglich an den Hersteller."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon ist blockiert"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kann nicht auf das Display gespiegelt werden"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Verwende ein anderes Kabel und versuch es noch einmal"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel unterstützt eventuell keine Bildschirme"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Dein USB-C-Kabel ist möglicherweise nicht zum Verbinden von Bildschirmen geeignet"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index af53ddfcfee8..7784e952ed3d 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Μπορεί να παρακολουθήσει τις αλληλεπιδράσεις σας με μια εφαρμογή ή έναν αισθητήρα εξοπλισμού και να αλληλεπιδράσει με εφαρμογές εκ μέρους σας."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ναι"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Όχι"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Επιλέξτε τις λειτουργίες που θέλετε να χρησιμοποιείτε με τη συντόμευση κουμπιού έντασης ήχου"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Σαββατοκύριακο"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Συμβάν"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ύπνος"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"Το τρίτο μέρος <xliff:g id="THIRD_PARTY">%1$s</xliff:g> θέτει ορισμένους ήχους σε σίγαση"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας. Επικοινωνήστε με τον κατασκευαστή σας για λεπτομέρειες."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Το μικρόφωνο έχει αποκλειστεί"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Δεν είναι δυνατός ο κατοπτρισμός στην οθόνη"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Χρησιμοποιήστε άλλο καλώδιο και δοκιμάστε ξανά"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Το καλώδιο μπορεί να μην υποστηρίζει οθόνες"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Το καλώδιο USB-C που έχετε ίσως να μην μπορεί να συνδεθεί σωστά σε οθόνες"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Διπλή οθόνη"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 8917a8203285..72f907cd9484 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"It can track your interactions with an app or a hardware sensor, and interact with apps on your behalf."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Allow"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Deny"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tap a feature to start using it:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choose features to use with the Accessibility button"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choose features to use with the volume key shortcut"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Can\'t mirror to display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Please use a different cable and try again"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cable may not support displays"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Your USB-C cable may not connect to displays properly"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 5a0ed859e441..3381e97a06d8 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"It can track your interactions with an app or a hardware sensor and interact with apps on your behalf."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Allow"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Deny"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tap a feature to start using it:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choose features to use with the accessibility button"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choose features to use with the volume key shortcut"</string> @@ -1904,6 +1908,8 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string> + <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string> + <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2342,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Can\'t mirror to display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Use a different cable and try again"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"Your device is too warm and can\'t mirror to the display until it cools down"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cable may not support displays"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Your USB-C cable may not connect to displays properly"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index bcf0790bae59..6975a65451c0 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"It can track your interactions with an app or a hardware sensor, and interact with apps on your behalf."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Allow"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Deny"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tap a feature to start using it:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choose features to use with the Accessibility button"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choose features to use with the volume key shortcut"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Can\'t mirror to display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Please use a different cable and try again"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cable may not support displays"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Your USB-C cable may not connect to displays properly"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 7ebffc6895c7..8f63abda4505 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"It can track your interactions with an app or a hardware sensor, and interact with apps on your behalf."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Allow"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Deny"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tap a feature to start using it:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choose features to use with the Accessibility button"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choose features to use with the volume key shortcut"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Can\'t mirror to display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Please use a different cable and try again"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cable may not support displays"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Your USB-C cable may not connect to displays properly"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index b739768c2068..ac2d58c77efa 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"It can track your interactions with an app or a hardware sensor, and interact with apps on your behalf."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Allow"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Deny"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tap a feature to start using it:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choose features to use with the accessibility button"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choose features to use with the volume key shortcut"</string> @@ -1904,6 +1908,8 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sleeping"</string> + <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string> + <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2342,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microphone is blocked"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Can\'t mirror to display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Use a different cable and try again"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"Your device is too warm and can\'t mirror to the display until it cools down"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cable may not support displays"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Your USB-C cable may not connect to displays properly"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index ca9ff13550d3..cd83e421c92e 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Puede realizar el seguimiento de tus interacciones con una app o un sensor de hardware, así como interactuar con las apps por ti."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rechazar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Presiona una función para comenzar a usarla:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Selecciona las funciones a utilizar con el botón de accesibilidad"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona las funciones a usar con las teclas de volumen"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Existe un problema interno con el dispositivo. Comunícate con el fabricante para obtener más información."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"No se puede duplicar la pantalla"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Usa un cable diferente y vuelve a intentarlo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Es posible que el cable no admita pantallas"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Es posible que el cable USB-C no se conecte a las pantallas de manera adecuada"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index b76229a8563f..bfd877eb443f 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Puede registrar tus interacciones con una aplicación o un sensor de hardware, así como interactuar con las aplicaciones en tu nombre."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Denegar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toca una función para empezar a usarla:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Selecciona qué funciones usar con el botón de accesibilidad"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Selecciona qué funciones usar con la tecla de volumen"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Durmiendo"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas el estado de fábrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Se ha producido un problema interno en el dispositivo. Ponte en contacto con el fabricante para obtener más información."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"No se puede proyectar a la pantalla"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Usa otro cable y vuelve a intentarlo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"El cable puede no ser compatible con pantallas"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Puede que tu cable USB‑C no sea adecuado para conectarse a pantallas"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index 4a8666ee1459..dbb7663e0d0e 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"See saab jälgida teie suhtlust rakenduse või riistvaraanduriga ja teie eest rakendustega suhelda."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Luba"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Keela"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Puudutage funktsiooni, et selle kasutamist alustada."</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Valige funktsioonid, mida juurdepääsetavuse nupuga kasutada"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Valige helitugevuse nupu otsetee funktsioonid"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nädalavahetus"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Sündmus"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Magamine"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistab teatud helid"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Seadmes ilmnes sisemine probleem. Üksikasjaliku teabe saamiseks võtke ühendust tootjaga."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon on blokeeritud"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ei saa ekraanile peegeldada"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Kasutage teist kaablit ja proovige uuesti"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kaabel ei pruugi ekraane toetada"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Teie USB-C-kaabel ei pruugi ekraanidega õigesti ühendust luua"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 86eaf0a08e1d..a35236f9dd5c 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Aplikazioekin edo hardware-sentsoreekin dituzun interakzioen jarraipena egin dezake, eta zure izenean beste aplikazio batzuekin interakzioan jardun."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Baimendu"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Ukatu"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Eginbide bat erabiltzen hasteko, saka ezazu:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoiarekin"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Aukeratu zein eginbide erabili nahi duzun bolumen-botoien lasterbidearekin"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Asteburua"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Gertaera"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Lo egiteko"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> soinu batzuk isilarazten ari da"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Barneko arazo bat dago zure gailuan. Xehetasunak jakiteko, jarri fabrikatzailearekin harremanetan."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Blokeatuta dago mikrofonoa"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ezin da islatu pantailan"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Erabili beste kable bat eta saiatu berriro"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Baliteke kablea pantailekin bateragarria ez izatea"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Baliteke USB-C kablea behar bezala ez konektatzea pantailetara"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index c5a2ee62d891..c9df9d1fbd53 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -166,7 +166,7 @@ <string name="httpErrorTimeout" msgid="7446272815190334204">"زمان اتصال به سرور تمام شده است."</string> <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"این صفحه دارای تعداد بسیار زیادی تغییر مسیر سرور است."</string> <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"پروتکل پشتیبانی نمیشود."</string> - <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"اتصال امن ایجاد نشد."</string> + <string name="httpErrorFailedSslHandshake" msgid="546319061228876290">"اتصال ایمن ایجاد نشد."</string> <string name="httpErrorBadUrl" msgid="754447723314832538">"بهدلیل نامعتبر بودن نشانی اینترنتی، صفحه باز نمیشود."</string> <string name="httpErrorFile" msgid="3400658466057744084">"دسترسی به فایل انجام نشد."</string> <string name="httpErrorFileNotFound" msgid="5191433324871147386">"فایل درخواستی پیدا نشد."</string> @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"این عملکرد میتواند با برنامه یا حسگری سختافزاری تعاملاتتان را ردیابی کند و ازطرف شما با برنامهها تعامل داشته باشد."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"اجازه دادن"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"انتخاب ویژگیهای موردنظر برای استفاده با میانبر کلید میزان صدا"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"آخر هفته"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"رویداد"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"خوابیدن"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> درحال قطع کردن بعضی از صداهاست"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی دادههای کارخانه انجام نگیرد، بیثبات بماند."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"دستگاهتان یک مشکل داخلی دارد. برای جزئیات آن با سازندهتان تماس بگیرید."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"میکروفون مسدود شد"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"بازتاب دادن به نمایشگر ممکن نبود"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"از کابل دیگری استفاده کنید و دوباره امتحان کنید"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"شاید کابل از نمایشگر پشتیبانی نکند"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"کابل USB-C شما ممکن است بهدرستی به نمایشگرها وصل نشود"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 4a08b9006696..69a65a2e5c2a 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Se voi seurata toimintaasi sovelluksella tai laitteistoanturilla ja käyttää sovelluksia puolestasi."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Salli"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Estä"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Aloita ominaisuuden käyttö napauttamalla sitä:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Valitse ominaisuudet, joita käytetään esteettömyyspainikkeella"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Valitse ominaisuudet, joita käytetään äänenvoimakkuuspikanäppäimellä"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Viikonloppuna"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tapahtuma"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Nukkuminen"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mykistää joitakin ääniä"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Laitteesi yhdistäminen ei onnistu sisäisen virheen takia. Saat lisätietoja valmistajalta."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoni on estetty"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Näytön peilaaminen ei onnistu"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Käytä eri johtoa ja yritä uudelleen"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Johto ei ehkä tue näyttöjä"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C-johtosi ei ehkä yhdisty näyttöihin kunnolla"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Kaksoisnäyttö"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 1b637db1e0d7..acdfaab7ed01 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut faire le suivi de vos interactions avec une application ou un capteur matériel et interagir avec des applications en votre nom."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toucher une fonctionnalité pour commencer à l\'utiliser :"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choisir les fonctionnalités à utiliser à l\'aide du bouton d\'accessibilité"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choisir les fonctionnalités à utiliser avec le raccourci des touches de volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semaine"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Le microphone est bloqué"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Impossible de dupliquer l\'écran"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Utilisez un câble différent et réessayez"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Le câble peut ne pas être compatible avec les écrans"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Votre câble USB-C peut ne pas se connecter correctement aux écrans"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 4f8de0c36867..a96b17939908 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Le service peut suivre vos interactions avec une application ou un capteur matériel, et interagir avec des applications de votre part."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Appuyez sur une fonctionnalité pour commencer à l\'utiliser :"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choisir les fonctionnalités à utiliser avec le bouton Accessibilité"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choisir les fonctionnalités à utiliser avec le raccourci des touches de volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Week-end"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Événement"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sommeil"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> coupe certains sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne lié à votre appareil est survenu. Veuillez contacter le fabricant pour en savoir plus."</string> @@ -2337,15 +2345,17 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Le micro est bloqué"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Duplication impossible"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Utilisez un autre câble et réessayez"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Le câble n\'est peut-être pas compatible avec les écrans"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Votre câble USB-C n\'est peut-être pas connecté correctement à l\'écran"</string> - <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Double écran"</string> - <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Double écran activé"</string> + <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> + <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"Dual Screen activé"</string> <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise les deux écrans pour afficher du contenu"</string> <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"L\'appareil est trop chaud"</string> - <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Double écran n\'est pas disponible, car votre téléphone surchauffe"</string> - <string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"Double écran n\'est pas disponible"</string> - <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"Double écran n\'est pas disponible, car Économiseur de batterie est activé. Vous pouvez désactiver cette option dans les paramètres."</string> + <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen n\'est pas disponible, car votre téléphone surchauffe"</string> + <string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"Dual Screen n\'est pas disponible"</string> + <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"Dual Screen n\'est pas disponible, car l\'économiseur de batterie est activé. Vous pouvez désactiver cette option dans les paramètres."</string> <string name="device_state_notification_settings_button" msgid="691937505741872749">"Accédez aux paramètres"</string> <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Désactiver"</string> <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configuré"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index b25cfcb82d1d..d001e90b23f7 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pode facer un seguimento das túas interaccións cunha aplicación ou cun sensor de hardware, así como interactuar por ti coas aplicacións."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Denegar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tocar unha función para comezar a utilizala:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escoller as funcións que queres utilizar co botón Accesibilidade"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolle as funcións que queres utilizar co atallo da tecla de volume"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Durmindo"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando algúns sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Produciuse un erro interno no teu dispositivo e quizais funcione de maneira inestable ata o restablecemento dos datos de fábrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Produciuse un erro interno co teu dispositivo. Contacta co teu fabricante para obter máis información."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"O micrófono está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Non se pode proxectar contido na pantalla"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Cambia de cable e téntao de novo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Pode que o cable non sexa compatible con pantallas"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"O teu cable USB-C pode que non se conecte ás pantallas de maneira adecuada"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index fae5ebc3279c..8b54db5f3946 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"તે ઍપ અથવા હાર્ડવેર સેન્સર વડે તમારી ક્રિયાપ્રતિક્રિયાને ટ્રૅક કરી શકે છે અને તમારા વતી ઍપ સાથે ક્રિયાપ્રતિક્રિયા કરી શકે છે."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"મંજૂરી આપો"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"નકારો"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"વૉલ્યૂમ કી શૉર્ટકટ વડે તમે ઉપયોગમાં લેવા માગો છો તે સુવિધાઓ પસંદ કરો"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"સપ્તાહાંત"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ઇવેન્ટ"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"નિષ્ક્રિય"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> અમુક અવાજોને મ્યૂટ કરે છે"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે અને જ્યાં સુધી તમે ફેક્ટરી ડેટા ફરીથી સેટ કરશો નહીં ત્યાં સુધી તે અસ્થિર રહી શકે છે."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે. વિગતો માટે તમારા નિર્માતાનો સંપર્ક કરો."</string> @@ -2011,7 +2019,7 @@ <string name="app_category_image" msgid="7307840291864213007">"ફોટો અને છબીઓ"</string> <string name="app_category_social" msgid="2278269325488344054">"સામાજિક અને સંચાર"</string> <string name="app_category_news" msgid="1172762719574964544">"સમાચાર અને સામાયિકો"</string> - <string name="app_category_maps" msgid="6395725487922533156">"Maps અને નેવિગેશન"</string> + <string name="app_category_maps" msgid="6395725487922533156">"Maps અને નૅવિગેશન"</string> <string name="app_category_productivity" msgid="1844422703029557883">"ઉત્પાદકતા"</string> <string name="app_category_accessibility" msgid="6643521607848547683">"ઍક્સેસિબિલિટી"</string> <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"ડિવાઇસ સ્ટૉરેજ"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"માઇક્રોફોનને બ્લૉક કરવામાં આવ્યો છે"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ડિસ્પ્લે પર મિરર કરી શકાતું નથી"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"બીજા કોઈ કેબલનો ઉપયોગ કરો અને ફરી પ્રયાસ કરો"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"શક્ય છે કે કેબલ કદાચ ડિસ્પ્લેને સપોર્ટ ન આપતો હોય"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"તમારો USB-C કેબલ કદાચ ડિસ્પ્લે સાથે યોગ્ય રીતે કનેક્ટ ન થાય"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index d4eb380098f8..87313a5f0ae9 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"यह आपके और किसी ऐप्लिकेशन या हार्डवेयर सेंसर के बीच होने वाले इंटरैक्शन को ट्रैक कर सकता है और आपकी तरफ़ से ऐप्लिकेशन के साथ इंटरैक्ट कर सकता है."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"अनुमति दें"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"इंकार करें"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"चुनें कि आवाज़ कम या ज़्यादा करने वाले बटन के शॉर्टकट से आप किन सुविधाओं का इस्तेमाल करना चाहते हैं"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"सप्ताहांत"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"इवेंट"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"सोते समय"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> कुछ आवाज़ें म्यूट कर रहा है"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"आपके डिवाइस में कोई अंदरूनी समस्या है और यह तब तक ठीक नहीं होगी जब तक आप फ़ैक्टरी डेटा रीसेट नहीं करते."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"माइक्रोफ़ोन को ब्लॉक किया गया है"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"डिसप्ले का कॉन्टेंट नहीं दिखाया जा सकता"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"कोई दूसरा केबल इस्तेमाल करके फिर से कोशिश करें"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ऐसा हो सकता है कि केबल, डिसप्ले के साथ ठीक से काम न करे"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ऐसा हो सकता है कि यूएसबी-सी केबल, डिसप्ले के साथ ठीक से कनेक्ट न हो पाए"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 977f88173117..c5e52bb9f8ad 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Može pratiti vaše interakcije s aplikacijama ili senzorom uređaja i stupati u interakciju s aplikacijama u vaše ime."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dopusti"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odbij"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Dodirnite značajku da biste je počeli koristiti:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Odabir značajki za upotrebu pomoću gumba za Pristupačnost"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Odabir značajki za upotrebu pomoću prečaca tipki za glasnoću"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Događaj"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spavanje"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Na vašem uređaju postoji interni problem. Obratite se proizvođaču za više pojedinosti."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Zrcaljenje na zaslon nije moguće"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Upotrijebite drugi kabel i pokušajte ponovno"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel možda ne podržava zaslone"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Vaš USB-C kabel možda nije ispravno povezan sa zaslonima"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dvostruki zaslon"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 9a389db091b7..39e49f67db64 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Követheti az alkalmazásokkal és hardveres érzékelőkkel való interakcióit, és műveleteket végezhet az alkalmazásokkal az Ön nevében."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Engedélyezés"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tiltás"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Koppintson valamelyik funkcióra a használatához:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Kiválaszthatja a Kisegítő lehetőségek gombbal használni kívánt funkciókat"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Kiválaszthatja a hangerőgombbal használni kívánt funkciókat"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hétvége"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Esemény"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Alvás"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> lenémít néhány hangot"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Belső probléma van az eszközzel. A részletekért vegye fel a kapcsolatot a gyártóval."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"A mikrofon le van tiltva"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nem lehet tükrözni a kijelzőre"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Használjon másik kábelt, és próbálja újra"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Előfordulhat, hogy a kábel nem támogatja a kijelzőket"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Előfordulhat, hogy az USB-C kábellel nem csatlakoztathatók megfelelően a kijelzők"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 9c2c2c5daa2c..75c7c747d9e3 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Կարող է հետագծել ձեր գործողությունները հավելվածներում և սարքակազմի սենսորների վրա, ինչպես նաև հավելվածներում կատարել գործողություններ ձեր անունից։"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Թույլատրել"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Մերժել"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Ընտրեք գործառույթները, որոնք կբացվեն ձայնի կարգավորման կոճակի միջոցով"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Շաբաթ-կիրակի"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Միջոցառում"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Քնի ժամանակ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ն անջատում է որոշ ձայներ"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Սարքում ներքին խնդիր է առաջացել: Մանրամասների համար կապվեք արտադրողի հետ:"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Խոսափողն արգելափակված է"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Չհաջողվեց հայելապատճենել էկրանին"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Օգտագործեք այլ մալուխ և նորից փորձեք"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Մալուխը կարող է համատեղելի չլինել էկրանների հետ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Հնարավոր է՝ USB-C մալուխը սխալ է միացված էկրանին"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 5bc62c2f227d..2d55f087600f 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Voice Access dapat melacak interaksi Anda dengan aplikasi atau sensor hardware, dan berinteraksi dengan aplikasi untuk Anda."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Izinkan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tolak"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ketuk fitur untuk mulai menggunakannya:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Pilih fitur yang akan digunakan dengan tombol aksesibilitas"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Pilih fitur yang akan digunakan dengan pintasan tombol volume"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Akhir pekan"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Acara"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Tidur"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mematikan beberapa suara"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Ada masalah dengan perangkat. Hubungi produsen perangkat untuk informasi selengkapnya."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon diblokir"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Tidak dapat mencerminkan ke layar"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gunakan kabel lain dan coba lagi"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel mungkin tidak mendukung layar"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kabel USB-C mungkin tidak terhubung dengan benar ke layar"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index f666308bb537..f5ad24b04053 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Það getur fylgst með samskiptum þínum við forrit eða skynjara vélbúnaðar og haft samskipti við forrit fyrir þína hönd."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Leyfa"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Hafna"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ýttu á eiginleika til að byrja að nota hann:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Veldu eiginleika sem á að nota með aðgengishnappinum"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Veldu eiginleika sem á að nota með flýtileið hljóðstyrkstakka"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helgi"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Viðburður"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Svefn"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> þaggar í einhverjum hljóðum"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Innra vandamál kom upp í tækinu. Hafðu samband við framleiðanda til að fá nánari upplýsingar."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Lokað er fyrir hljóðnemann"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ekki er hægt að spegla á skjá"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Notaðu aðra snúru og reyndu aftur"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Ekki er víst að snúran styðji skjái"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Ekki er víst að USB-C-snúran tengist skjám á réttan hátt"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tveir skjáir"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 9ffadbe08fd1..80262d2cc597 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Può tenere traccia delle tue interazioni con un\'app o un sensore hardware e interagire con app per tuo conto."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Consenti"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rifiuta"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tocca una funzionalità per iniziare a usarla:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Scegli le funzionalità da usare con il pulsante Accessibilità"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Scegli le funzionalità da usare con la scorciatoia dei tasti del volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fine settimana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Notte"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> sta disattivando alcuni suoni"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Si è verificato un problema interno con il dispositivo. Per informazioni dettagliate, contatta il produttore."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfono bloccato"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Impossibile eseguire il mirroring al display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Usa un altro cavo e riprova"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Il cavo potrebbe non supportare i display"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Il cavo USB-C potrebbe non collegarsi correttamente ai display"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Doppio schermo"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 53ec382af0f1..59dc3b27e8e1 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"אפשרות למעקב אחר האינטראקציה שלך עם אפליקציות או חיישני חומרה, וביצוע אינטראקציה בשמך."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"אישור"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"עדיף שלא"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"בחירת תכונות לשימוש עם מקש הקיצור לעוצמת הקול"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"סוף השבוע"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"אירוע"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"שינה"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"חלק מהצלילים מושתקים על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהוא לא יתפקד כראוי עד שיבוצע איפוס לנתוני היצרן."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"קיימת בעיה פנימית במכשיר שלך. לקבלת פרטים, יש ליצור קשר עם היצרן."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"המיקרופון חסום"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"לא ניתן לשקף למסך"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"צריך להשתמש בכבל שונה ולנסות שוב"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"יכול להיות שהכבל לא תומך במסכים"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"יכול להיות שכבל ה-USB-C לא יתחבר למסכים כמו שצריך"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"מצב שני מסכים"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index ab865aa2ba00..2ac444bdaea9 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"アプリやハードウェア センサーの操作を記録したり、自動的にアプリを操作したりできます。"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"許可"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"許可しない"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"音量ボタンのショートカットで使用する機能の選択"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"予定"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠中"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> により一部の音はミュートに設定"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"デバイスで内部的な問題が発生しました。データが初期化されるまで不安定になる可能性があります。"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"デバイスで内部的な問題が発生しました。詳しくはメーカーにお問い合わせください。"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"マイクがブロックされています"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ディスプレイにミラーリングできません"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"別のケーブルでもう一度お試しください"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ケーブルはディスプレイに対応していない可能性があります"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C ケーブルがディスプレイに正しく接続されていない可能性があります"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"デュアル スクリーン"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 27f596bf7390..8da54ce39653 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"მას შეუძლია თვალი მიადევნოს თქვენს ინტერაქციებს აპის ან აპარატურის სენსორის საშუალებით, ასევე, თქვენი სახელით აწარმოოს აპებთან ინტერაქცია."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"დაშვება"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"უარყოფა"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"აირჩიეთ ფუნქციები, რომელთა გამოყენებაც გსურთ ხმის ღილაკის მალსახმობით"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"შაბათ-კვირა"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"მოვლენა"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ძილისას"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ზოგიერთ ხმას ადუმებს"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ფიქსირდება თქვენი მ ოწყობილობის შიდა პრობლემა და შეიძლება არასტაბილური იყოს, სანამ ქარხნულ მონაცემების არ განაახლებთ."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ფიქსირდება თქვენი მოწყობილობის შიდა პრობლემა. დეტალებისათვის, მიმართეთ თქვენს მწარმოებელს."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"მიკროფონი დაბლოკილია"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ეკრანზე არეკვლა შეუძლებელია"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"გამოიყენეთ სხვა კაბელი და ცადეთ ხელახლა"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"კაბელს შეიძლება არ ჰქონდეს ეკრანების მხარდაჭერა"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"თქვენი USB-C კაბელი შეიძლება სათანადოდ არ უკავშირდებოდეს ეკრანებს"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ორმაგი ეკრანი"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 1faea616398e..935fa75c6291 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1690,7 +1690,7 @@ <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Жою"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"Дыбыс деңгейін ұсынылған деңгейден көтеру керек пе?\n\nЖоғары дыбыс деңгейінде ұзақ кезеңдер бойы тыңдау есту қабілетіңізге зиян тигізуі мүмкін."</string> <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="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">"Түймелер тіркесімі қосулы кезде, екі дыбыс түймесін 3 секунд басып тұрсаңыз, \"Арнайы мүмкіндіктер\" функциясы іске қосылады."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Арнайы мүмкіндіктердің жылдам пәрмені іске қосылсын ба?"</string> @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ол қолданбамен немесе жабдық датчигімен істеген тапсырмаларыңызды бақылайды және қолданбаларды сіздің атыңыздан пайдаланады."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Рұқсат ету"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Тыйым салу"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Дыбыс деңгейі пернелері тіркесімімен қолданылатын функцияларды таңдаңыз"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Демалыс күндері"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Іс-шара"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ұйқы режимі"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> кейбір дыбыстарды өшіруде"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон блокталған."</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Дисплейге көшірмені көрсету мүмкін емес"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Басқа кабельмен әрекетті қайталап көріңіз."</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабель дисплейлерді қолдамауы мүмкін"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C кабелі дисплейлерге дұрыс жалғанбаған болуы мүмкін."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 470c39ed2ee6..95d6ca165628 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"វាអាចតាមដានអន្តរកម្មរបស់អ្នកជាមួយនឹងកម្មវិធី ឬសេនស័រហាតវែរ និងធ្វើអន្តរកម្មជាមួយកម្មវិធីនានាជំនួសឱ្យអ្នក។"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"អនុញ្ញាត"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"បដិសេធ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ជ្រើសរើសមុខងារ ដើម្បីប្រើជាមួយផ្លូវកាត់គ្រាប់ចុចកម្រិតសំឡេង"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ចុងសប្ដាហ៍"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ព្រឹត្តិការណ៍"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"កំពុងដេក"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> កំពុងបិទសំឡេងមួយចំនួន"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ហើយវាអ្នកមិនមានស្ថេរភាព រហូតទាល់តែអ្នកកំណត់ដូចដើមវិញទាំងស្រុង។"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ទំនាក់ទំនងក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកសម្រាប់ព័ត៌មានបន្ថែម។"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"មីក្រូហ្វូនត្រូវបានទប់ស្កាត់"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"មិនអាចបញ្ចាំងទៅផ្ទាំងអេក្រង់បានទេ"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"ប្រើខ្សែផ្សេង រួចព្យាយាមម្តងទៀត"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ខ្សែប្រហែលជាមិនអាចប្រើជាមួយផ្ទាំងអេក្រង់បានទេ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ខ្សែ USB-C របស់អ្នកប្រហែលជាមិនអាចភ្ជាប់ផ្ទាំងអេក្រង់បានត្រឹមត្រូវទេ"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"អេក្រង់ពីរ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index e2f24f69122e..b6bef49256af 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1689,8 +1689,8 @@ <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ತೆಗೆದುಹಾಕು"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ವಾಲ್ಯೂಮ್ ಅನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾದ ಮಟ್ಟಕ್ಕಿಂತಲೂ ಹೆಚ್ಚು ಮಾಡಬೇಕೆ?\n\nದೀರ್ಘ ಅವಧಿಯವರೆಗೆ ಹೆಚ್ಚಿನ ವಾಲ್ಯೂಮ್ನಲ್ಲಿ ಆಲಿಸುವುದರಿಂದ ನಿಮ್ಮ ಆಲಿಸುವಿಕೆ ಸಾಮರ್ಥ್ಯಕ್ಕೆ ಹಾನಿಯುಂಟು ಮಾಡಬಹುದು."</string> - <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="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">"ಶಾರ್ಟ್ಕಟ್ ಆನ್ ಆಗಿರುವಾಗ, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಬಟನ್ಗಳನ್ನು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಒತ್ತಿದರೆ ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ವೈಶಿಷ್ಟ್ಯವೊಂದು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ."</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ವೈಶಿಷ್ಟ್ಯಗಳಿಗಾಗಿ ಶಾರ್ಟ್ಕಟ್ ಆನ್ ಮಾಡಬೇಕೇ?"</string> @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ಇದು ಆ್ಯಪ್ ಅಥವಾ ಹಾರ್ಡ್ವೇರ್ ಸೆನ್ಸರ್ನ ಜೊತೆಗಿನ ನಿಮ್ಮ ಸಂವಹನಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಬಹುದು, ಮತ್ತು ನಿಮ್ಮ ಪರವಾಗಿ ಆ್ಯಪ್ಗಳ ಜೊತೆ ಸಂವಹನ ನಡೆಸಬಹುದು."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ಅನುಮತಿಸಿ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ನಿರಾಕರಿಸಿ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ವಾಲ್ಯೂಮ್ ಕೀ ಶಾರ್ಟ್ಕಟ್ ಜೊತೆಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ವಾರಾಂತ್ಯ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ಈವೆಂಟ್"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ನಿದ್ರೆಯ ಸಮಯ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ. ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ತಯಾರಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ಡಿಸ್ಪ್ಲೇಗೆ ಪ್ರತಿಬಿಂಬಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"ಬೇರೆ ಕೇಬಲ್ ಬಳಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ಡಿಸ್ಪ್ಲೇಗಳನ್ನು ಕೇಬಲ್ ಬೆಂಬಲಿಸದಿರಬಹುದು"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ನಿಮ್ಮ USB-C ಕೇಬಲ್ ಡಿಸ್ಪ್ಲೇಗಳಿಗೆ ಸರಿಯಾಗಿ ಕನೆಕ್ಟ್ ಆಗದಿರಬಹುದು"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 4ed97fe01828..612bc7111378 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"앱 또는 하드웨어 센서와의 상호작용을 추적할 수 있으며 나를 대신해 앱과 상호작용할 수 있습니다."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"허용"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"거부"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"볼륨 키 단축키로 사용할 기능 선택"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"주말"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"캘린더 일정"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"수면 시간"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>(이)가 일부 소리를 음소거함"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"사용 중인 기기 내부에 문제가 발생했습니다. 자세한 내용은 제조업체에 문의하세요."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"마이크가 차단됨"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"디스플레이에 미러링할 수 없음"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"다른 케이블을 사용하여 다시 시도해 보세요."</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"디스플레이를 지원하지 않는 케이블일 수 있음"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"사용 중인 USB-C 케이블이 디스플레이에 제대로 연결되지 않을 수 있습니다."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 421284b2a0e1..ab92325140b8 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Кызмат колдонмодо жасаган аракеттериңизге же түзмөктүн сенсорлоруна көз салып, сиздин атыңыздан буйруктарды берет."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ооба"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Жок"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Үндү катуулатуу/акырындатуу баскычтары менен кайсы функцияларды иштеткиңиз келет?"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Дем алыш"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Иш-чара"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Уйку режими"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> айрым үндөрдү өчүрүүдө"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Түзмөгүңүздө ички көйгөй бар жана ал баштапкы абалга кайтарылмайынча туруктуу иштебей коюшу мүмкүн."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Түзмөгүңүздө ички көйгөй бар. Анын чоо-жайын билүү үчүн өндүрүүчүңүзгө кайрылыңыз."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон бөгөттөлгөн"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Экранга күзгүдөй чагылдыруу мүмкүн эмес"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Башка кабелди колдонуп, кайра аракет кылыңыз"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабель дисплейлерди колдоого албашы мүмкүн"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C кабели дисплейлерге туура туташпашы мүмкүн"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Кош экран"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index c743fc0b7b23..c4f74d04f834 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ມັນສາມາດຕິດຕາມການໂຕ້ຕອບຂອງທ່ານກັບແອັບ ຫຼື ເຊັນເຊີຮາດແວໃດໜຶ່ງ ແລະ ໂຕ້ຕອບກັບແອັບໃນນາມຂອງທ່ານໄດ້."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ອະນຸຍາດ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ປະຕິເສດ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທາງລັດປຸ່ມລະດັບສຽງ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ທ້າຍອາທິດ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ການນັດໝາຍ"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ການນອນ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ປິດສຽງບາງຢ່າງໄວ້"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ມີບັນຫາພາຍໃນກັບອຸປະກອນຂອງທ່ານ, ແລະມັນອາດຈະບໍ່ສະຖຽນຈົນກວ່າທ່ານຕັ້ງເປັນຂໍ້ມູນໂຮງງານຄືນແລ້ວ."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ມີບັນຫາພາຍໃນກັບອຸປະກອນຂອງທ່ານ. ຕິດຕໍ່ຜູ້ຜະລິດຂອງທ່ານສຳລັບລາຍລະອຽດຕ່າງໆ."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ໄມໂຄຣໂຟນຖືກບລັອກໄວ້"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ບໍ່ສາມາດສະທ້ອນໄປຫາຈໍສະແດງຜົນໄດ້"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"ກະລຸນາໃຊ້ສາຍອື່ນແລ້ວລອງໃໝ່"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ສາຍອາດບໍ່ຮອງຮັບຈໍສະແດງຜົນ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ສາຍ USB-C ຂອງທ່ານອາດບໍ່ໄດ້ເຊື່ອມຕໍ່ກັບຈໍສະແດງຜົນຢ່າງຖືກຕ້ອງ"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ໜ້າຈໍຄູ່"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index ff665c5bbf8e..96303beb19c9 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Naudojant šią funkciją galima stebėti jūsų sąveiką su programa ar aparatinės įrangos jutikliu ir sąveikauti su programomis jūsų vardu."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Leisti"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Atmesti"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Norėdami naudoti funkciją, palieskite ją:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Funkcijų, kurioms bus naudojamas pritaikomumo mygtukas, pasirinkimas"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Funkcijų, kurioms bus naudojamas garsumo spartusis klavišas, pasirinkimas"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Savaitgalį"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Įvykis"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Miegas"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"„<xliff:g id="THIRD_PARTY">%1$s</xliff:g>“ nutildo kai kuriuos garsus"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Iškilo vidinė su jūsų įrenginiu susijusi problema. Jei reikia išsamios informacijos, susisiekite su gamintoju."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonas užblokuotas"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Negalima bendrinti ekrano vaizdo ekrane"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Naudokite kitą laiką ir bandykite dar kartą"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Laidas gali nepalaikyti ekranų"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Gali būti, kad USB-C laidu nepavyksta tinkamai prisijungti prie ekranų"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 4d369aaeb8d7..1aa526ca31cd 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Tā var izsekot jūsu mijiedarbību ar lietotni vai aparatūras sensoru un mijiedarboties ar lietotnēm jūsu vārdā."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Atļaut"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Neatļaut"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Pieskarieties funkcijai, lai sāktu to izmantot"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Izvēlieties funkcijas, ko izmantot ar pieejamības pogu"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Izvēlieties funkcijas, ko izmantot ar skaļuma pogu saīsni"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nedēļas nogalē"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Pasākums"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Gulēšana"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izslēdz noteiktas skaņas"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Jūsu ierīcē ir radusies iekšēja problēma. Lai iegūtu plašāku informāciju, lūdzu, sazinieties ar ražotāju."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofons ir bloķēts."</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nevar spoguļot displeju"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Izmantojiet citu vadu un mēģiniet vēlreiz."</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Iespējams, vads neatbalsta displejus"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Iespējams, jūsu USB-C vads nevarēs nodrošināt pareizu savienojumu ar displejiem."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen režīms"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 29c9de8368d1..79c663d3f696 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Може да ја следи вашата интеракција со апликациите или со хардверските сензори и да врши интеракција со апликациите во ваше име."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволи"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Одбиј"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Изберете ги функциите што ќе ги користите со кратенката за копчето за јачина на звук"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Настан"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спиење"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> исклучи некои звуци"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Настана внатрешен проблем со уредот и може да биде нестабилен сè додека не ресетирате на фабричките податоци."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Настана внатрешен проблем со уредот. Контактирајте го производителот за детали."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофонот е блокиран"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Не може да се отсликува за прикажување"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Користете друг кабел и обидете се повторно"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабелот можеби не поддржува екрани"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Кабелот USB-C можеби нема да се поврзе правилно со екраните"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 46587ee13086..e281426d04af 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ഇതിന് ഒരു ആപ്പുമായോ ഹാർഡ്വെയർ സെൻസറുമായോ ഉള്ള നിങ്ങളുടെ ആശയവിനിമയങ്ങൾ ട്രാക്ക് ചെയ്യാനും നിങ്ങളുടെ പേരിൽ ആശയവിനിമയം നടത്താനും കഴിയും."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"അനുവദിക്കൂ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"നിരസിക്കുക"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"വോളിയം കീ കുറുക്കുവഴിയിലൂടെ ഉപയോഗിക്കാൻ ഫീച്ചറുകൾ തിരഞ്ഞെടുക്കുക"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"വാരാന്ത്യം"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ഇവന്റ്"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ഉറക്കം"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ചില ശബ്ദങ്ങൾ മ്യൂട്ട് ചെയ്യുന്നു"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്നമുണ്ട്, ഫാക്ടറി വിവര പുനഃസജ്ജീകരണം ചെയ്യുന്നതുവരെ ഇതു അസ്ഥിരമായിരിക്കാനിടയുണ്ട്."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്നമുണ്ട്. വിശദാംശങ്ങൾക്കായി നിർമ്മാതാവിനെ ബന്ധപ്പെടുക."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"മൈക്രോഫോൺ ബ്ലോക്ക് ചെയ്തു"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ഡിസ്പ്ലേയിലേക്ക് മിറർ ചെയ്യാനാകില്ല"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"മറ്റൊരു കേബിൾ ഉപയോഗിച്ച് വീണ്ടും ശ്രമിക്കുക"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"കേബിൾ, ഡിസ്പ്ലേകളെ പിന്തുണച്ചേക്കില്ല"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"നിങ്ങളുടെ USB-C കേബിൾ, ഡിസ്പ്ലേകളിലേക്ക് ശരിയായി കണക്റ്റ് ആയേക്കില്ല"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"ഡ്യുവൽ സ്ക്രീൻ"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 62a162e75540..6615ac7457dc 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Энэ нь таны апп болон техник хангамжийн мэдрэгчтэй хийх харилцан үйлдлийг хянах болон таны өмнөөс апптай харилцан үйлдэл хийх боломжтой."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Зөвшөөрөх"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Татгалзах"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Дууны түвшний түлхүүрийн товчлолын тусламжтай ашиглах онцлогуудыг сонгоно уу"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Амралтын өдөр"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Үйл явдал"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Унтлагын цаг"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> зарим дууны дууг хааж байна"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Таны төхөөрөмжид дотоод алдаа байна.Та төхөөрөмжөө үйлдвэрээс гарсан төлөвт шилжүүлэх хүртэл таны төхөөрөмж чинь тогтворгүй байж болох юм."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Таны төхөөрөмжид дотоод алдаа байна. Дэлгэрэнгүй мэдээлэл авахыг хүсвэл үйлдвэрлэгчтэйгээ холбоо барина уу."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофоныг блоклосон байна"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Дэлгэцэд тусгал үүсгэх боломжгүй"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Өөр кабель ашиглаад, дахин оролдоно уу"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабель нь дэлгэцүүдийг дэмждэггүй байж магадгүй"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Таны USB-C кабель дэлгэцүүдэд зохих ёсоор холбогдохгүй байж магадгүй"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 87227eee7079..6bfa0bfbf328 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"हे तुमचा ॲप किंवा हार्डवेअर सेन्सरसोबतचा परस्परसंवाद ट्रॅक करू शकते आणि इतर ॲप्ससोबत तुमच्या वतीने संवाद साधू शकते."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"अनुमती द्या"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"नकार द्या"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"व्हॉल्यूम की शॉर्टकटसोबत वापरायची असलेली ॲप्स निवडा"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"आठवड्याच्या शेवटी"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"इव्हेंट"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"झोपताना"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्वनी म्यूट करत आहे"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"आपल्या डिव्हाइसमध्ये अंतर्गत समस्या आहे आणि तुमचा फॅक्टरी डेटा रीसेट होईपर्यंत ती अस्थिर असू शकते."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"आपल्या डिव्हाइसमध्ये अंतर्गत समस्या आहे. तपशीलांसाठी आपल्या निर्मात्याशी संपर्क साधा."</string> @@ -2336,6 +2344,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"मायक्रोफोन ब्लॉक केलेला आहे"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"डिस्प्लेवर मिरर करू शकत नाही"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"वेगळी केबल वापरून पुन्हा प्रयत्न करा"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"तुमचे डिव्हाइस खूप गरम आहे आणि ते थंड होईपर्यंत डिस्प्लेमध्ये मिरर करू शकत नाही"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"केबल कदाचित डिस्प्लेना सपोर्ट करणार नाही"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"तुमची USB-C केबल कदाचित डिस्प्लेना योग्यरीत्या कनेक्ट होणार नाही"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index 7794150ea86e..769f0bddf55d 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ciri ini boleh menjejaki interaksi anda dengan apl atau penderia perkakasan dan berinteraksi dengan apl bagi pihak anda."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Benarkan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tolak"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Ketik ciri untuk mula menggunakan ciri itu:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Pilih ciri untuk digunakan dengan butang kebolehaksesan"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Pilih ciri untuk digunakan dengan pintasan kekunci kelantangan"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hujung minggu"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Acara"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Tidur"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> meredamkan sesetengah bunyi"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Terdapat masalah dalaman dengan peranti anda. Hubungi pengilang untuk mengetahui butirannya."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon disekat"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Tidak dapat menyegerakkan kepada paparan"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gunakan kabel lain dan cuba lagi"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel mungkin tidak menyokong paparan"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kabel USB-C anda mungkin tidak bersambung kepada paparan dengan betul"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dwiskrin"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index fcc98d4f913f..df94876358ed 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"၎င်းသည် သင်နှင့် အက်ပ်တစ်ခု (သို့) အာရုံခံကိရိယာအကြား ပြန်လှန်တုံ့ပြန်မှုများကို မှတ်သားနိုင်ပြီး သင့်ကိုယ်စား အက်ပ်များနှင့် ပြန်လှန်တုံ့ပြန်နိုင်သည်။"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ခွင့်ပြုရန်"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ပယ်ရန်"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"အသံခလုတ် ဖြတ်လမ်းလင့်ခ်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုများကို ရွေးပါ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"စနေ၊ တနင်္ဂနွေ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"အစီအစဉ်"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"အိပ်နေချိန်"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> သည် အချို့အသံကို ပိတ်နေသည်"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"မိုက်ခရိုဖုန်း ပိတ်ထားသည်"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ဖန်သားပြင်တွင် စကရင်ပွား၍ မရပါ"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"အခြားကေဘယ်ကြိုးသုံးပြီး ထပ်စမ်းကြည့်ပါ"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ကေဘယ်ကြိုးက ဖန်သားပြင်များကို မပံ့ပိုးခြင်း ဖြစ်နိုင်သည်"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"သင့် USB-C ကေဘယ်ကြိုးသည် ဖန်သားပြင်များနှင့် မှန်ကန်စွာ ချိတ်ဆက်မထားခြင်း ဖြစ်နိုင်သည်"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 9d6e8050de50..4aca6fc6fa64 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan spore kommunikasjonen din med en app eller maskinvaresensor og kommunisere med apper på dine vegne."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Tillat"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Avvis"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Trykk på en funksjon for å begynne å bruke den:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Velg funksjonene du vil bruke med Tilgjengelighet-knappen"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Velg funksjonene du vil bruke med volumtastsnarveien"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helg"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Aktivitet"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sover"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår av noen lyder"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Det har oppstått et internt problem på enheten din. Ta kontakt med produsenten for mer informasjon."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen er blokkert"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kan ikke speile til skjermen"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Bruk en annen kabel og prøv igjen"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabelen støtter kanskje ikke skjermer"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C-kabelen din kobler seg kanskje ikke til skjermer på riktig måte"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index bd9853af7d20..16279129f730 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"यसले कुनै एप वा हार्डवेयर सेन्सरसँग तपाईंले गर्ने अन्तर्क्रिया ट्र्याक गर्न सक्छ र तपाईंका तर्फबाट एपहरूसँग अन्तर्क्रिया गर्न सक्छ।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"अनुमति दिनुहोस्"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"नदिनुहोस्"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"भोल्युम कुञ्जीको सर्टकटमार्फत प्रयोग गर्न चाहेका सुविधाहरू छनौट गर्नुहोस्"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"शनिबार"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"कार्यक्रम"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"निदाएका बेला"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ले केही ध्वनिहरू म्युट गर्दै छ"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ। विवरणहरूको लागि आफ्नो निर्मातासँग सम्पर्क गर्नुहोस्।"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"माइक्रोफोन म्युट गरिएको छ"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"डिस्प्लेमा मिरर गर्न सकिएन"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"अर्कै केबल प्रयोग गरी फेरि प्रयास गर्नुहोस्"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"यो केबल डिस्प्लेहरूमा प्रयोग गर्न नमिल्न सक्छ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"तपाईंको USB-C केबल डिस्प्लेहरूमा राम्रोसँग नजोडिन सक्छ"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index a4bedd325af2..5ae7d6d25372 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Deze functie kan je interacties met een app of een hardwaresensor bijhouden en namens jou met apps communiceren."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Toestaan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Weigeren"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tik op een functie om deze te gebruiken:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Functies kiezen voor gebruik met de knop Toegankelijkheid"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Functies kiezen voor gebruik met de sneltoets via de volumeknop"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Afspraken"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Slapen"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> zet sommige geluiden uit"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Er is een intern probleem met je apparaat. Neem contact op met de fabrikant voor meer informatie."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfoon is geblokkeerd"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Kan niet spiegelen naar scherm"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gebruik een andere kabel en probeer het opnieuw"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"De kabel ondersteunt misschien geen schermen"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Je USB-C-kabel sluit misschien niet goed aan op schermen"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index af76df84f3d0..9997f165bde6 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1689,8 +1689,8 @@ <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"କାଢ଼ି ଦିଅନ୍ତୁ"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ମାତ୍ରା ବଢ଼ାଇ ସୁପାରିଶ ସ୍ତର ବଢ଼ାଉଛନ୍ତି? \n\n ଲମ୍ବା ସମୟ ପର୍ଯ୍ୟନ୍ତ ଉଚ୍ଚ ଶବ୍ଦରେ ଶୁଣିଲେ ଆପଣଙ୍କ ଶ୍ରବଣ ଶକ୍ତି ଖରାପ ହୋଇପାରେ।"</string> - <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="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">"ସର୍ଟକଟ୍ ଚାଲୁ ଥିବା ବେଳେ, ଉଭୟ ଭଲ୍ୟୁମ୍ ବଟନ୍ 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇବା ଦ୍ୱାରା ଏକ ଆକ୍ସେସବିଲିଟି ଫିଚର୍ ଆରମ୍ଭ ହେବ।"</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ଆକ୍ସେସିବିଲିଟୀ ଫିଚରଗୁଡ଼ିକ ପାଇଁ ସର୍ଟକଟ୍ ଚାଲୁ କରିବେ?"</string> @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ଏହା କୌଣସି ଆପ କିମ୍ବା ହାର୍ଡୱେର ସେନ୍ସର ସହ ଆପଣଙ୍କର ଇଣ୍ଟେରାକ୍ସନକୁ ଟ୍ରାକ କରିପାରେ ଏବଂ ଆପଣଙ୍କ ତରଫରୁ ଆପ୍ସ ସହ ଇଣ୍ଟରାକ୍ଟ କରିପାରେ।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ଅନୁମତି"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ଅଗ୍ରାହ୍ୟ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ଭଲ୍ୟୁମ୍ କୀ ସର୍ଟକଟ୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଫିଚରଗୁଡ଼ିକ ବାଛନ୍ତୁ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ସପ୍ତାହାନ୍ତ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ଇଭେଣ୍ଟ"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ଶୋଇବା"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> କିଛି ସାଉଣ୍ଡକୁ ମ୍ୟୁଟ୍ କରୁଛି"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ଆପଣଙ୍କ ଡିଭାଇସ୍ରେ ଏକ ସମସ୍ୟା ରହିଛି ଏବଂ ଆପଣ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଅସ୍ଥିର ରହିପାରେ।"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଏକ ସମସ୍ୟା ରହିଛି। ବିବରଣୀ ପାଇଁ ଆପଣଙ୍କ ଉତ୍ପାଦକଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ମାଇକ୍ରୋଫୋନକୁ ବ୍ଲକ କରାଯାଇଛି"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ଡିସପ୍ଲେ କରିବାକୁ ମିରର କରାଯାଇପାରିବ ନାହିଁ"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"ଏକ ଭିନ୍ନ କେବୁଲ ବ୍ୟବହାର କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"କେବୁଲ ଡିସପ୍ଲେଗୁଡ଼ିକୁ ସମର୍ଥନ କରିନପାରେ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ଆପଣଙ୍କ USB-C କେବୁଲ ଡିସପ୍ଲେଗୁଡ଼ିକ ସହ ସଠିକ ଭାବରେ କନେକ୍ଟ ହୋଇନପାରେ"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 1db544a21b42..4b9289dfd457 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1689,8 +1689,8 @@ <string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"ਹਟਾਓ"</string> <string name="safe_media_volume_warning" product="default" msgid="3751676824423049994">"ਕੀ ਵੌਲਿਊਮ ਸਿਫ਼ਾਰਸ਼ ਕੀਤੇ ਪੱਧਰ ਤੋਂ ਵਧਾਉਣੀ ਹੈ?\n\nਲੰਮੇ ਸਮੇਂ ਤੱਕ ਉੱਚ ਵੌਲਿਊਮ ਤੇ ਸੁਣਨ ਨਾਲ ਤੁਹਾਡੀ ਸੁਣਨ ਸ਼ਕਤੀ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚ ਸਕਦਾ ਹੈ।"</string> - <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="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">"ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਹੋਣ \'ਤੇ, ਕਿਸੇ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਬਟਨਾਂ ਨੂੰ 3 ਸਕਿੰਟ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।"</string> <string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"ਕੀ ਪਹੁੰਚਯੋਗਤਾ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਲਈ ਸ਼ਾਰਟਕੱਟ ਚਾਲੂ ਕਰਨਾ ਹੈ?"</string> @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ਇਹ ਕਿਸੇ ਐਪ ਜਾਂ ਹਾਰਡਵੇਅਰ ਸੈਂਸਰ ਦੇ ਨਾਲ ਤੁਹਾਡੀਆਂ ਅੰਤਰਕਿਰਿਆਵਾਂ ਨੂੰ ਟਰੈਕ ਕਰ ਸਕਦੀ ਹੈ, ਅਤੇ ਤੁਹਾਡੀ ਤਰਫ਼ੋਂ ਐਪਾਂ ਦੇ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰ ਸਕਦੀ ਹੈ।"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ਕਰਨ ਦਿਓ"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ਨਾ ਕਰਨ ਦਿਓ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ਅਵਾਜ਼ ਕੁੰਜੀ ਸ਼ਾਰਟਕੱਟ ਨਾਲ ਵਰਤਣ ਲਈ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਚੁਣੋ"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ਹਫ਼ਤੇ ਦਾ ਅੰਤਲਾ ਦਿਨ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ਇਵੈਂਟ"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"ਸੌਣ ਵੇਲੇ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਕੁਝ ਧੁਨੀਆਂ ਨੂੰ ਮਿਊਟ ਕਰ ਰਹੀ ਹੈ"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਸੀ। ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਨਿਰਮਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ਡਿਸਪਲੇ \'ਤੇ ਪ੍ਰਤਿਬਿੰਬਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"ਕੋਈ ਵੱਖਰੀ ਕੇਬਲ ਵਰਤ ਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੇਬਲ ਡਿਸਪਲੇਆਂ ਦਾ ਸਮਰਥਨ ਨਾ ਕਰੇ"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਤੁਹਾਡੀ USB-C ਕੇਬਲ ਡਿਸਪਲੇਆਂ ਨਾਲ ਠੀਕ ਤਰ੍ਹਾਂ ਕਨੈਕਟ ਨਾ ਹੋਵੇ"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index f708f7de715f..0273cc34a175 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Może śledzić Twoje interakcje z aplikacjami lub czujnikiem sprzętowym, a także obsługiwać aplikacje za Ciebie."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Zezwól"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Odmów"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Wybierz funkcję, aby zacząć z niej korzystać:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Wybierz funkcje, których chcesz używać z przyciskiem ułatwień dostępu"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Wybierz funkcje, do których chcesz używać skrótu z klawiszami głośności"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Wydarzenie"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Sen"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> wycisza niektóre dźwięki"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"W Twoim urządzeniu wystąpił problem wewnętrzny. Skontaktuj się z jego producentem, by otrzymać szczegółowe informacje."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon jest zablokowany"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nie można utworzyć odbicia lustrzanego na wyświetlaczu"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Użyj innego kabla i spróbuj ponownie"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel może nie obsługiwać wyświetlaczy"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kabel USB-C może nie łączyć się prawidłowo z wyświetlaczami"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Podwójny ekran"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index b3b0e26f6a4e..ec7658da99bf 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pode monitorar suas interações com um app ou um sensor de hardware e interagir com apps em seu nome."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Negar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toque em um recurso para começar a usá-lo:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escolha recursos para usar com o botão de acessibilidade"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolha recursos para usar com o atalho da tecla de volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Não é possível espelhar a tela"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Use outro cabo e tente de novo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Talvez o cabo não tenha suporte a telas"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Seu cabo USB-C pode não se conectar a telas corretamente"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tela dupla"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 784f2a9ca4d0..b834c0f1f48d 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pode monitorizar as suas interações com uma app ou um sensor de hardware e interagir com apps em seu nome."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Recusar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toque numa funcionalidade para começar a utilizá-la:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escolha funcionalidades para utilizar com o botão Acessibilidade"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolha funcionalidades para usar com o atalho das teclas de volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"A dormir"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está a desativar alguns sons."</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Existe um problema interno no seu dispositivo. Contacte o fabricante para obter mais informações."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Não é possível espelhar para o ecrã"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Use um cabo diferente e tente novamente"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"O cabo pode não suportar ecrãs"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"O cabo USB-C pode não se ligar a ecrãs corretamente"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index b3b0e26f6a4e..ec7658da99bf 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Pode monitorar suas interações com um app ou um sensor de hardware e interagir com apps em seu nome."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permitir"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Negar"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toque em um recurso para começar a usá-lo:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Escolha recursos para usar com o botão de acessibilidade"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Escolha recursos para usar com o atalho da tecla de volume"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Evento"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Dormir"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"O microfone está bloqueado"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Não é possível espelhar a tela"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Use outro cabo e tente de novo"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Talvez o cabo não tenha suporte a telas"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Seu cabo USB-C pode não se conectar a telas corretamente"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Tela dupla"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 88f5044eefdf..dc89003efa3d 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Poate să urmărească interacțiunile tale cu o aplicație sau cu un senzor hardware și să interacționeze cu aplicații în numele tău."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Permite"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuz"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Atinge o funcție ca să începi să o folosești:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Alege funcțiile pe care să le folosești cu butonul de accesibilitate"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Alege funcțiile pentru comanda rapidă a butonului de volum"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Eveniment"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Somn"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> dezactivează anumite sunete"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"A apărut o problemă internă pe dispozitiv. Pentru detalii, contactează producătorul."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Microfonul este blocat"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nu se poate oglindi pe ecran"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Folosește alt cablu și încearcă din nou"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Cablul poate să nu fie compatibil cu ecranele"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Cablul USB-C poate să nu se conecteze corespunzător la ecrane"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 7f5e87f2bbb7..8bd65763bbae 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Сервис может отслеживать ваше взаимодействие с приложениями и датчиками устройства и давать приложениям команды от вашего имени."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Разрешить"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Отклонить"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Выберите функции, которые будут запускаться с помощью кнопки регулировки громкости"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выходные"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Мероприятие"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Время сна"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> приглушает некоторые звуки."</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Произошла внутренняя ошибка, и устройство может работать нестабильно, пока вы не выполните сброс настроек."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Произошла внутренняя ошибка. Обратитесь к производителю устройства за подробными сведениями."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон заблокирован."</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Не удается дублировать на экран"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Используйте другой кабель или повторите попытку."</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабель может не подходить для подключения к дисплеям"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Возможно, подключение дисплеев с помощью этого кабеля USB-C не поддерживается."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index e90f1a2cea22..cba8d477ca3b 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"මෙයට යෙදුමක් හෝ දෘඪාංග සංවේදකයක් සමඟ ඔබේ අන්තර්ක්රියා හඹා යෑමට, සහ ඔබ වෙනුවෙන් යෙදුම් සමඟ අන්තර්ක්රියාවේ යෙදීමට හැකි ය."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ඉඩ දෙන්න"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ප්රතික්ෂේප කරන්න"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"හඬ පරිමා යතුරු කෙටිමග සමග භාවිත කිරීමට විශේෂාංග තෝරා ගන්න"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"සති අන්තය"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"සිදුවීම"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"නිදා ගනිමින්"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> සමහර ශබ්ද නිහඬ කරමින්"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"ඔබේ උපාංගය සමගින් ගැටලුවක් ඇති අතර, ඔබේ කර්මාන්තශාලා දත්ත යළි සකසන තෙක් එය අස්ථායි විය හැකිය."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"ඔබේ උපාංගය සමගින් අභ්යන්තර ගැටලුවක් ඇත. විස්තර සඳහා ඔබේ නිෂ්පාදක අමතන්න."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"මයික්රෆෝනය අවහිර කර ඇත"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"සංදර්ශකයට දර්පණය කළ නොහැක"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"වෙනස් කේබලයක් භාවිතා කර නැවත උත්සාහ කරන්න"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"කේබලය සංදර්ශක වෙත සහාය නොදැක්විය හැක"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ඔබේ USB-C කේබලයට සංදර්ශකවලට නිසි ලෙස සම්බන්ධ නොවිය හැක"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 3da576c4fd5a..61a88201ab05 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Môže sledovať vaše interakcie s aplikáciou alebo hardvérovým senzorom a interagovať s aplikáciami za vás."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Povoliť"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zamietnuť"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Klepnutím na funkciu ju začnite používať:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Výber funkcií, ktoré chcete používať tlačidlom dostupnosti"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Výber funkcií, ktoré chcete používať klávesovou skratkou"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Udalosť"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spánok"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypína niektoré zvuky"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho výrobné nastavenia."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Vo vašom zariadení došlo k internému problému. Ak chcete získať podrobné informácie, obráťte sa na jeho výrobcu."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofón je blokovaný"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nedá sa zrkadliť do obrazovky"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Použite iný kábel a skúste znova"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kábel nemusí podporovať obrazovky"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kábel USB‑C sa nemusí dať správne pripojiť k obrazovkám"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 5b731b730398..97f91f3408e4 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali tipalom strojne opreme ter komunicira z aplikacijami v vašem imenu."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dovoli"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zavrni"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Če želite začeti uporabljati funkcijo, se je dotaknite:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Izberite funkcije, ki jih želite uporabljati z gumbom za dostopnost"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Izberite funkcije, ki jih želite uporabljati z bližnjico na tipki za glasnost"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Konec tedna"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Dogodek"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Spanje"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izklaplja nekatere zvoke"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Vaša naprava ima notranjo napako. Če želite več informacij, se obrnite na proizvajalca."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon je blokiran"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ni mogoče zrcaliti zaslona"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Uporabite drug kabel in poskusite znova"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel morda ne podpira zaslonov"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kabel USB-C se morda ne more ustrezno povezati z zasloni."</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index a4fd1bf18b39..ea5795d38e44 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Lejo"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzo"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Trokit te një veçori për të filluar ta përdorësh atë:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Zgjidh veçoritë që do të përdorësh me butonin e qasshmërisë"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Zgjidh veçoritë që do të përdorësh me shkurtoren e tastit të volumit"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fundjava"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Ngjarje"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Në gjumë"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> po çaktivizon disa tinguj"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Ka një problem të brendshëm me pajisjen tënde. Ajo mund të jetë e paqëndrueshme derisa të rivendosësh të dhënat në gjendje fabrike."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Ka një problem të brendshëm me pajisjen tënde. Kontakto prodhuesin tënd për detaje."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofoni është i bllokuar"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Nuk mund të pasqyrojë tek ekrani"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Përdor një kabllo tjetër dhe provo përsëri"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kablloja nuk mund të mbështetë ekranet"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Kablloja jote USB-C mund të mos lidhet siç duhet me ekranet"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index e5ae2f71a226..e5bb5a973817 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1711,6 +1711,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Може да прати интеракције са апликацијом или сензором хардвера и користи апликације уместо вас."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволи"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Одбиј"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Одаберите функције за пречицу тастером јачине звука"</string> @@ -1905,6 +1909,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Догађај"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Спавање"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Дошло је до интерног проблема у вези са уређајем. Потражите детаље од произвођача."</string> @@ -2337,6 +2345,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Микрофон је блокиран"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Пресликавање на екран није могуће"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Употребите други кабл и пробајте поново"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабл не подржава екране"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C кабл се не повезује правилно са екранима"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index f3917fe70d17..d80c7590444f 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Den kan registrera din användning av en app eller maskinvarusensor och interagera med appar åt dig."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Tillåt"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Neka"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Tryck på funktioner som du vill aktivera:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Välj vilka funktioner du vill använda med hjälp av tillgänglighetsknappen"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Välj att funktioner att använda med hjälp av volymknappskortkommandot"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"I helgen"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Händelse"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"När jag sover"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> stänger av vissa ljud"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Ett internt problem har uppstått i enheten. Kontakta tillverkaren om du vill veta mer."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofonen är blockerad"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Det går inte spegla till skärmen"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Använd en annan kabel och försök igen"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabeln kanske inte har stöd för skärmar"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Det kanske inte går att ansluta skärmar korrekt med den här USB-C-kabeln"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 022331c6fd9f..3c2a02bc7ce7 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Inaweza kufuatilia mawasiliano yako na programu au kitambuzi cha maunzi na kuwasiliana na programu zingine kwa niaba yako."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ruhusu"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Kataa"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Gusa kipengele ili uanze kukitumia:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Chagua vipengele vya kutumia na kitufe cha zana za ufikivu"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Chagua vipengele vya kutumia na njia ya mkato ya kitufe cha sauti"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wikendi"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tukio"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Kulala"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> inazima baadhi ya sauti"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Kuna hitilafu ya ndani ya kifaa chako. Wasiliana na mtengenezaji wa kifaa chako kwa maelezo."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Maikrofoni imezuiwa"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Imeshindwa kuakisi kwenye skrini"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Tumia kebo tofauti kisha ujaribu tena"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Huenda kebo haioani na skrini"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Huenda kebo yako ya USB-C isiunganishwe vizuri na skrini"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 9ad4bd2bfb72..79bc2a472108 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ஏதேனும் ஆப்ஸ் அல்லது வன்பொருள் சென்சாரின் உதவியுடன் உரையாடல்களைக் கண்காணித்து உங்கள் சார்பாக ஆப்ஸுடன் உரையாட இச்சேவையால் இயலும்."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"அனுமதி"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"நிராகரி"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"ஒலியளவு விசை ஷார்ட்கட் மூலம் பயன்படுத்த விரும்பும் அம்சங்களைத் தேர்வுசெய்யுங்கள்"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"வார இறுதி"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"நிகழ்வு"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"உறக்கத்தில்"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> சில ஒலிகளை முடக்குகிறது"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது, அதனை ஆரம்பநிலைக்கு மீட்டமைக்கும் வரை நிலையற்று இயங்கலாம்."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது. விவரங்களுக்கு சாதன தயாரிப்பாளரைத் தொடர்புகொள்ளவும்."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"மைக்ரோஃபோன் முடக்கப்பட்டுள்ளது"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"டிஸ்ப்ளேயில் பிரதிபலிக்க முடியவில்லை"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"வெவ்வேறு கேபிள்களைப் பயன்படுத்தி மீண்டும் முயலவும்"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"டிஸ்ப்ளேக்களைக் கேபிள் ஆதரிக்காமல் இருக்கக்கூடும்"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"டிஸ்ப்ளேக்களில் உங்கள் USB-C கேபிள் சரியாக இணைக்கப்படாமல் இருக்கக்கூடும்"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"இரட்டைத் திரை"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index d1c336d863f7..a2862ba3123c 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్తో చేసే ఇంటరాక్షన్లను లేదా హార్డ్వేర్ సెన్సార్ను ట్రాక్ చేస్తూ మీ తరఫున యాప్లతో ఇంటరాక్ట్ చేయగలదు."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"వద్దు"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"వాల్యూమ్ కీ షార్ట్కట్తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"వారాంతం"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ఈవెంట్"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"నిద్రావస్థ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> కొన్ని ధ్వనులను మ్యూట్ చేస్తోంది"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది మరియు మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసే వరకు అస్థిరంగా ఉంటుంది."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది. వివరాల కోసం మీ తయారీదారుని సంప్రదించండి."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"మైక్రోఫోన్ బ్లాక్ చేయబడింది"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"డిస్ప్లే చేయడానికి మిర్రర్ చేయడం సాధ్యపడదు"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"వేరే కేబుల్ను ఉపయోగించి, మళ్లీ ట్రై చేయండి"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"డిస్ప్లేలను కేబుల్ సపోర్ట్ చేయకపోవచ్చు"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"మీ USB-C కేబుల్, డిస్ప్లేలకు సరిగ్గా కనెక్ట్ కాకపోవచ్చు"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 06920b0f58f5..16e7611788c7 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"การควบคุมนี้สามารถติดตามการโต้ตอบของคุณกับแอปหรือกับเซ็นเซอร์ของฮาร์ดแวร์ และโต้ตอบกับแอปต่างๆ แทนคุณ"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"อนุญาต"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"ปฏิเสธ"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"เลือกฟีเจอร์ที่จะใช้กับทางลัดปุ่มปรับระดับเสียง"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"สุดสัปดาห์"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"กิจกรรม"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"นอนหลับ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> กำลังปิดเสียงบางรายการ"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง อุปกรณ์อาจทำงานไม่เสถียรจนกว่าคุณจะรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง โปรดติดต่อผู้ผลิตเพื่อขอรายละเอียดเพิ่มเติม"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"ไมโครโฟนถูกบล็อก"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"มิเรอร์ไปยังจอแสดงผลไม่ได้"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"โปรดใช้สายอื่นและลองอีกครั้ง"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"สายสัญญาณอาจไม่รองรับจอแสดงผล"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"สาย USB-C อาจเชื่อมต่อกับจอแสดงผลอย่างไม่ถูกต้อง"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 2477698e740d..b2a7f25fa771 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Masusubaybayan nito ang iyong mga pakikipag-ugayan sa isang app o hardware na sensor, at puwede itong makipag-ugnayan sa mga app para sa iyo."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Payagan"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Tanggihan"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"I-tap ang isang feature para simulan itong gamitin:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Pumili ng mga feature na gagana sa pamamagitan ng button ng accessibility"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Pumili ng mga feature na gagana sa pamamagitan ng shortcut ng volume key"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Event"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Pag-sleep"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"Minu-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g> ang ilang tunog"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"May internal na problema sa iyong device. Makipag-ugnayan sa iyong manufacturer upang malaman ang mga detalye."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Naka-block ang mikropono"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Hindi makapag-mirror sa display"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Gumamit ng ibang cable at subukan ulit"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Posibleng hindi sinusuportahan ng cable ang mga display"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Posibleng hindi kumonekta nang maayos sa mga display ang iyong USB-C cable"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 5598dbc914ac..eb58785bbf5f 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Bir uygulama veya donanım sensörüyle etkileşimlerinizi takip edebilir ve sizin adınıza uygulamalarla etkileşimde bulunabilir."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"İzin ver"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Reddet"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Kullanmaya başlamak için bir özelliğe dokunun:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Erişilebilirlik düğmesiyle kullanılacak özellikleri seçin"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Ses tuşu kısayoluyla kullanılacak özellikleri seçin"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hafta sonu"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Etkinlik"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Uyku"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bazı sesleri kapatıyor"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Cihazınızla ilgili dahili bir sorun oluştu. Ayrıntılı bilgi için üreticinizle iletişim kurun."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon engellenmiş"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ekrana yansıtılamıyor"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Farklı kablo kullanarak tekrar deneyin"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kablo, ekranları desteklemeyebilir"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C kablonuz ekranlara doğru şekilde bağlanamayabilir"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index d4cd2071bd87..393fa761a086 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1712,6 +1712,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Цей сервіс може відстежувати вашу взаємодію з додатком чи апаратним датчиком, а також взаємодіяти з додатками від вашого імені."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Дозволити"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Заборонити"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"Виберіть функції для комбінації з клавішами гучності"</string> @@ -1906,6 +1910,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"На вихідних"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Подія"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Під час сну"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає деякі звуки"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Через внутрішню помилку ваш пристрій може працювати нестабільно. Відновіть заводські налаштування."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"На пристрої сталася внутрішня помилка. Зв’яжіться з виробником пристрою, щоб дізнатися більше."</string> @@ -2338,6 +2346,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Мікрофон заблоковано"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Неможливо дублювати на дисплей"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Скористайтесь іншим кабелем і повторіть спробу"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Кабель може не підтримувати дисплеї"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Ваш кабель USB-C може не підключатися до дисплеїв належним чином"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual Screen"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 8634294d5a05..9ea7348ef577 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"یہ کسی ایپ یا ہارڈویئر سینسر کے ساتھ آپ کے تعاملات کو ٹریک کر سکتا ہے، اور آپ کی طرف سے ایپس کے ساتھ تعامل کر سکتا ہے۔"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"اجازت دیں"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مسترد کریں"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"والیوم کلید کے شارٹ کٹ کے ساتھ استعمال کرنے کیلئے خصوصیات منتخب کریں"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ویک اینڈ"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ایونٹ"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"سونا"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> کچھ آوازوں کو خاموش کر رہا ہے"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"آپ کے آلہ میں ایک داخلی مسئلہ ہے اور جب تک آپ فیکٹری ڈیٹا کو دوبارہ ترتیب نہیں دے دیتے ہیں، ہوسکتا ہے کہ یہ غیر مستحکم رہے۔"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"آپ کے آلہ میں ایک داخلی مسئلہ ہے۔ تفصیلات کیلئے اپنے مینوفیکچرر سے رابطہ کریں۔"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"مائیکروفون مسدود ہے"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"ڈسپلے پر دو طرفہ مطابقت پذیری ممکن نہیں ہے"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"مختلف کیبل استعمال کریں اور دوبارہ کوشش کریں"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"ہو سکتا ہے کہ کیبل ڈسپلیز کو سپورٹ نہ کرے"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"ہو سکتا ہے کہ آپ کی USB-C کیبل مناسب طریقے سے ڈسپلیز سے منسلک نہ ہو"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"دوہری اسکرین"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index fdea194637ae..78f352906d1b 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ilova yoki qurilma sensori bilan munosabatlaringizni kuzatishi hamda sizning nomingizdan ilovalar bilan ishlashi mumkin."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Ruxsat"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Rad etish"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Kerakli funksiyani tanlang"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Qulayliklar tugmasi bilan foydalanish uchun funksiyalarni tanlang"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Tovush tugmasi bilan ishga tushiriladigan funksiyalarni tanlang"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Dam olish kunlari"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Tadbir"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Uyquda"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ayrim tovushlarni ovozsiz qilgan"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. Tafsilotlar uchun qurilmangiz ishlab chiqaruvchisiga murojaat qiling."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Mikrofon bloklandi"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Displeyga translatsiya qilinmaydi"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Boshqa kabel yordamida qayta urining"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Kabel displeylar bilan ishlamasligi mumkin"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C kabelingiz displeylarga toʻgʻri ulanmasligi mumkin"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Ikkita ekran"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 12a61edfca58..1b6ededd1d8a 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Dịch vụ này có thể theo dõi các hoạt động tương tác của bạn với một ứng dụng hoặc bộ cảm biến phần cứng, cũng như có thể thay mặt bạn tương tác với các ứng dụng."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Cho phép"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Từ chối"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Nhấn vào một tính năng để bắt đầu sử dụng:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Chọn các tính năng để dùng với nút hỗ trợ tiếp cận"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Chọn các tính năng để dùng với phím tắt là phím âm lượng"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cuối tuần"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Sự kiện"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ngủ"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> đang tắt một số âm thanh"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Đã xảy ra sự cố nội bộ với thiết bị. Hãy liên hệ với nhà sản xuất của bạn để biết chi tiết."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Micrô đang bị chặn"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Không chiếu được nội dung lên màn hình"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Hãy dùng một cáp khác rồi thử lại"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Có thể cáp không hỗ trợ màn hình"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Có thể cáp USB-C của bạn chưa kết nối đúng cách với màn hình"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Dual screen"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 2ae8fe653ded..676ab00f0464 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"此功能可以跟踪您与应用或硬件传感器的互动,并代表您与应用互动。"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"允许"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"拒绝"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"选择可通过音量键快捷方式使用的功能"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"周末"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"活动"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正在将某些音效设为静音"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"您的设备内部出现了问题。如果不将设备恢复出厂设置,设备运行可能会不稳定。"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"您的设备内部出现了问题。请联系您的设备制造商了解详情。"</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"麦克风已被屏蔽"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"无法镜像到显示屏"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"请改用其他数据线并重试"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"数据线可能不支持显示屏"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"您的 USB-C 数据线可能没有正确连接到显示屏"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"双屏幕"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index e10823824b59..76dabaf688f5 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"這項功能會追蹤你與應用程式或硬件感應器的互動,並代表你直接與應用程式互動。"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"允許"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"拒絕"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"選擇要用音量快速鍵的功能"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"活動"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正將某些音效設為靜音"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"你裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"你裝置的系統發生問題,請聯絡你的製造商瞭解詳情。"</string> @@ -2336,6 +2344,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"已封鎖麥克風"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"無法將畫面鏡像投放至螢幕"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"請改用其他連接線,然後再試一次"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"裝置過熱,請等到降溫後再將畫面鏡像投放至螢幕"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"連接線可能不支援顯示屏"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"你的 USB-C 連接線可能未妥善連接顯示屏"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"雙螢幕"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 5b6520168d5d..fc5f262f3ebc 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"可追蹤你與應用程式或硬體感應器的互動,並代表你與應用程式進行互動。"</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"允許"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"拒絕"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <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="1077294237378645981">"選擇要搭配音量快速鍵使用的功能"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"活動"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"睡眠"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"「<xliff:g id="THIRD_PARTY">%1$s</xliff:g>」正在關閉部分音效"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"你的裝置發生內部問題,必須將裝置恢復原廠設定才能解除不穩定狀態。"</string> <string name="system_error_manufacturer" msgid="703545241070116315">"你的裝置發生內部問題,詳情請洽裝置製造商。"</string> @@ -2336,6 +2344,7 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"麥克風已封鎖"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"無法將畫面鏡像投放至螢幕"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"請改用其他傳輸線,然後再試一次"</string> + <string name="connected_display_thermally_unavailable_notification_content" msgid="9205758199439955949">"裝置過熱,請等到降溫後再將畫面鏡像投放至螢幕"</string> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"傳輸線可能不支援螢幕"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"USB-C 傳輸線可能未妥善連接到螢幕"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"雙螢幕"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index b701abe18d93..a88d832b3636 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1710,6 +1710,10 @@ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ingalandela ukusebenzisana kwakho nohlelo lokusebenza noma inzwa yehadiwe, nokusebenzisana nezinhlelo zokusebenza engxenyeni yakho."</string> <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Vumela"</string> <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Phika"</string> + <!-- no translation found for accessibility_dialog_button_uninstall (2952465517671708108) --> + <skip /> + <!-- no translation found for accessibility_dialog_touch_filtered_warning (3741940116597822451) --> + <skip /> <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Thepha isici ukuqala ukusisebenzisa:"</string> <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Khetha izici ongazisebenzisa nenkinobho yokufinyeleleka"</string> <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Khetha izici ongazisebenzisa nesinqamuleli sokhiye wevolumu"</string> @@ -1904,6 +1908,10 @@ <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Ngempelasonto"</string> <string name="zen_mode_default_events_name" msgid="2280682960128512257">"Umcimbi"</string> <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"Ulele"</string> + <!-- no translation found for zen_mode_implicit_activated (2634285680776672994) --> + <skip /> + <!-- no translation found for zen_mode_implicit_deactivated (8688441768371501750) --> + <skip /> <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ithulisa eminye imisindo"</string> <string name="system_error_wipe_data" msgid="5910572292172208493">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string> <string name="system_error_manufacturer" msgid="703545241070116315">"Kukhona inkinga yangaphakathi ngedivayisi yakho. Xhumana nomkhiqizi wakho ukuze uthole imininingwane."</string> @@ -2336,6 +2344,8 @@ <string name="mic_access_off_toast" msgid="8111040892954242437">"Imakrofoni ivinjiwe"</string> <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Ayikwazi ukufanisa nesibonisi"</string> <string name="connected_display_unavailable_notification_content" msgid="3845903313751217516">"Sebenzisa ikhebuli ehlukile bese uyazama futhi"</string> + <!-- no translation found for connected_display_thermally_unavailable_notification_content (9205758199439955949) --> + <skip /> <string name="connected_display_cable_dont_support_displays_notification_title" msgid="8477183783847392465">"Ikhebuli ingase ingasekeli iziboniso"</string> <string name="connected_display_cable_dont_support_displays_notification_content" msgid="8080498819171483973">"Ikhebuli yakho ye-USB-C ingase ingaxhumi kahle kuzibonisi"</string> <string name="concurrent_display_notification_name" msgid="1526911253558311131">"Isikrini esikabili"</string> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 9f99dc94bc92..f8546b73a37e 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1592,6 +1592,12 @@ <!-- Whether attributions provided are meant to be user-visible. --> <attr name="attributionsAreUserVisible" format="boolean" /> + <!-- If a preloaded APK is marked updatableSystem = false, any request for an update will be rejected. + If an APK marked updatableSystem = false is being installed, regardless of the updatableSystem state + of the version it's replacing, the install will be rejected. + This is a private attribute, used without android: namespace. --> + <attr name="updatableSystem" format="boolean" /> + <!-- Specify the type of foreground service. Multiple types can be specified by ORing the flags together. --> <attr name="foregroundServiceType"> diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index 39d958cdf5ee..8d80af41680a 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -243,10 +243,6 @@ <bool name="allow_clear_initial_attach_data_profile">false</bool> <java-symbol type="bool" name="allow_clear_initial_attach_data_profile" /> - <!-- Boolean indicating whether TelephonyAnalytics module is active or not. --> - <bool name="telephony_analytics_switch">true</bool> - <java-symbol type="bool" name="telephony_analytics_switch" /> - <!-- Whether to enable modem on boot if behavior is not defined --> <bool name="config_enable_cellular_on_boot_default">true</bool> <java-symbol type="bool" name="config_enable_cellular_on_boot_default" /> diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java index 443dcb4e51c5..2315a58eb487 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java @@ -31,6 +31,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -59,6 +60,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; @@ -80,20 +83,32 @@ import java.util.stream.Collectors; @Presubmit public class TransactionExecutorTests { + @Mock + private ClientTransactionHandler mTransactionHandler; + @Mock + private ActivityLifecycleItem mActivityLifecycleItem; + @Mock + private IBinder mActivityToken; + @Mock + private Activity mActivity; + private TransactionExecutor mExecutor; private TransactionExecutorHelper mExecutorHelper; - private ClientTransactionHandler mTransactionHandler; private ActivityClientRecord mClientRecord; @Before public void setUp() throws Exception { - mTransactionHandler = mock(ClientTransactionHandler.class); + MockitoAnnotations.initMocks(this); mClientRecord = new ActivityClientRecord(); when(mTransactionHandler.getActivityClient(any())).thenReturn(mClientRecord); mExecutor = spy(new TransactionExecutor(mTransactionHandler)); mExecutorHelper = new TransactionExecutorHelper(); + + doReturn(true).when(mActivityLifecycleItem).isActivityLifecycleItem(); + doReturn(mActivityToken).when(mActivityLifecycleItem).getActivityToken(); + doReturn(mActivity).when(mTransactionHandler).getActivity(mActivityToken); } @Test @@ -229,23 +244,21 @@ public class TransactionExecutorTests { when(callback1.getPostExecutionState()).thenReturn(UNDEFINED); ClientTransactionItem callback2 = mock(ClientTransactionItem.class); when(callback2.getPostExecutionState()).thenReturn(UNDEFINED); - ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); - IBinder token = mock(IBinder.class); - when(stateRequest.getActivityToken()).thenReturn(token); - when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class)); ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addCallback(callback1); transaction.addCallback(callback2); - transaction.setLifecycleStateRequest(stateRequest); + transaction.setLifecycleStateRequest(mActivityLifecycleItem); transaction.preExecute(mTransactionHandler); mExecutor.execute(transaction); - InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest); + InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, + mActivityLifecycleItem); inOrder.verify(callback1).execute(eq(mTransactionHandler), any()); inOrder.verify(callback2).execute(eq(mTransactionHandler), any()); - inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any()); + inOrder.verify(mActivityLifecycleItem).execute(eq(mTransactionHandler), eq(mClientRecord), + any()); } @Test @@ -254,23 +267,21 @@ public class TransactionExecutorTests { when(callback1.getPostExecutionState()).thenReturn(UNDEFINED); ClientTransactionItem callback2 = mock(ClientTransactionItem.class); when(callback2.getPostExecutionState()).thenReturn(UNDEFINED); - ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); - IBinder token = mock(IBinder.class); - when(stateRequest.getActivityToken()).thenReturn(token); - when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class)); ClientTransaction transaction = ClientTransaction.obtain(null /* client */); transaction.addTransactionItem(callback1); transaction.addTransactionItem(callback2); - transaction.addTransactionItem(stateRequest); + transaction.addTransactionItem(mActivityLifecycleItem); transaction.preExecute(mTransactionHandler); mExecutor.execute(transaction); - InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest); + InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, + mActivityLifecycleItem); inOrder.verify(callback1).execute(eq(mTransactionHandler), any()); inOrder.verify(callback2).execute(eq(mTransactionHandler), any()); - inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any()); + inOrder.verify(mActivityLifecycleItem).execute(eq(mTransactionHandler), eq(mClientRecord), + any()); } @Test @@ -536,42 +547,36 @@ public class TransactionExecutorTests { @Test public void testActivityItemExecute() { - final IBinder token = mock(IBinder.class); final ClientTransaction transaction = ClientTransaction.obtain(null /* client */); final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class); when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED); - when(activityItem.getActivityToken()).thenReturn(token); + when(activityItem.getActivityToken()).thenReturn(mActivityToken); transaction.addCallback(activityItem); - final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); - transaction.setLifecycleStateRequest(stateRequest); - when(stateRequest.getActivityToken()).thenReturn(token); - when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class)); + transaction.setLifecycleStateRequest(mActivityLifecycleItem); mExecutor.execute(transaction); - final InOrder inOrder = inOrder(activityItem, stateRequest); + final InOrder inOrder = inOrder(activityItem, mActivityLifecycleItem); inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any()); - inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any()); + inOrder.verify(mActivityLifecycleItem).execute(eq(mTransactionHandler), eq(mClientRecord), + any()); } @Test public void testExecuteTransactionItems_activityItemExecute() { - final IBinder token = mock(IBinder.class); final ClientTransaction transaction = ClientTransaction.obtain(null /* client */); final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class); when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED); - when(activityItem.getActivityToken()).thenReturn(token); + when(activityItem.getActivityToken()).thenReturn(mActivityToken); transaction.addTransactionItem(activityItem); - final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); - transaction.addTransactionItem(stateRequest); - when(stateRequest.getActivityToken()).thenReturn(token); - when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class)); + transaction.addTransactionItem(mActivityLifecycleItem); mExecutor.execute(transaction); - final InOrder inOrder = inOrder(activityItem, stateRequest); + final InOrder inOrder = inOrder(activityItem, mActivityLifecycleItem); inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any()); - inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any()); + inOrder.verify(mActivityLifecycleItem).execute(eq(mTransactionHandler), eq(mClientRecord), + any()); } private static int[] shuffledArray(int[] inputArray) { diff --git a/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java b/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java new file mode 100644 index 000000000000..e19c4b15d300 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/LauncherActivityInfoTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import static com.google.common.truth.Truth.assertThat; + +import android.platform.test.annotations.Presubmit; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for {@link android.content.pm.LauncherActivityInfo} + */ +@Presubmit +@RunWith(AndroidJUnit4.class) +public class LauncherActivityInfoTest { + + @Test + public void testTrimStart() { + // Invisible case + assertThat(LauncherActivityInfo.trimStart("\u0009").toString()).isEmpty(); + // It is not supported in the system font + assertThat(LauncherActivityInfo.trimStart("\u0FE1").toString()).isEmpty(); + // Surrogates case + assertThat(LauncherActivityInfo.trimStart("\uD83E\uDD36").toString()) + .isEqualTo("\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trimStart("\u0009\u0FE1\uD83E\uDD36A").toString()) + .isEqualTo("\uD83E\uDD36A"); + assertThat(LauncherActivityInfo.trimStart("\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\uD83E\uDD36A\u0009\u0FE1"); + assertThat(LauncherActivityInfo.trimStart("A\uD83E\uDD36\u0009\u0FE1A").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A"); + assertThat(LauncherActivityInfo.trimStart( + "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trimStart( + "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\uD83E\uDD36A\u0009\u0FE1"); + } + + @Test + public void testTrimEnd() { + // Invisible case + assertThat(LauncherActivityInfo.trimEnd("\u0009").toString()).isEmpty(); + // It is not supported in the system font + assertThat(LauncherActivityInfo.trimEnd("\u0FE1").toString()).isEmpty(); + // Surrogates case + assertThat(LauncherActivityInfo.trimEnd("\uD83E\uDD36").toString()) + .isEqualTo("\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trimEnd("\u0009\u0FE1\uD83E\uDD36A").toString()) + .isEqualTo("\u0009\u0FE1\uD83E\uDD36A"); + assertThat(LauncherActivityInfo.trimEnd("\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\uD83E\uDD36A"); + assertThat(LauncherActivityInfo.trimEnd("A\uD83E\uDD36\u0009\u0FE1A").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A"); + assertThat(LauncherActivityInfo.trimEnd( + "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trimEnd( + "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\u0009\u0FE1\uD83E\uDD36A"); + } + + @Test + public void testTrim() { + // Invisible case + assertThat(LauncherActivityInfo.trim("\u0009").toString()).isEmpty(); + // It is not supported in the system font + assertThat(LauncherActivityInfo.trim("\u0FE1").toString()).isEmpty(); + // Surrogates case + assertThat(LauncherActivityInfo.trim("\uD83E\uDD36").toString()) + .isEqualTo("\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trim("\u0009\u0FE1\uD83E\uDD36A").toString()) + .isEqualTo("\uD83E\uDD36A"); + assertThat(LauncherActivityInfo.trim("\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\uD83E\uDD36A"); + assertThat(LauncherActivityInfo.trim("A\uD83E\uDD36\u0009\u0FE1A").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A"); + assertThat(LauncherActivityInfo.trim( + "A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36").toString()) + .isEqualTo("A\uD83E\uDD36\u0009\u0FE1A\uD83E\uDD36"); + assertThat(LauncherActivityInfo.trim( + "\u0009\u0FE1\uD83E\uDD36A\u0009\u0FE1").toString()) + .isEqualTo("\uD83E\uDD36A"); + } +} diff --git a/core/tests/coretests/src/android/service/notification/ConditionTest.java b/core/tests/coretests/src/android/service/notification/ConditionTest.java index 42629ba41287..612562eb22dc 100644 --- a/core/tests/coretests/src/android/service/notification/ConditionTest.java +++ b/core/tests/coretests/src/android/service/notification/ConditionTest.java @@ -16,17 +16,22 @@ package android.service.notification; +import static com.google.common.truth.Truth.assertThat; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; +import android.app.Flags; import android.net.Uri; import android.os.Parcel; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.google.common.base.Strings; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,8 +42,11 @@ import java.lang.reflect.Field; public class ConditionTest { private static final String CLASS = "android.service.notification.Condition"; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Test - public void testLongFields_inConstructors() { + public void testLongFields_inConstructors_classic() { String longString = Strings.repeat("A", 65536); Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530)); @@ -59,7 +67,7 @@ public class ConditionTest { } @Test - public void testLongFields_viaParcel() { + public void testLongFields_viaParcel_classic() { // Set fields via reflection to force them to be long, then parcel and unparcel to make sure // it gets truncated upon unparcelling. Condition cond = new Condition(Uri.parse("uri://placeholder"), "placeholder", @@ -98,4 +106,92 @@ public class ConditionTest { assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.line1.length()); assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.line2.length()); } + + @Test + public void testLongFields_inConstructors() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + String longString = Strings.repeat("A", 65536); + Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530)); + + // Confirm strings are truncated via short constructor + Condition cond1 = new Condition(longUri, longString, Condition.STATE_TRUE, + Condition.SOURCE_CONTEXT); + + assertThat(cond1.id.toString()).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(cond1.summary).hasLength(Condition.MAX_STRING_LENGTH); + + // Confirm strings are truncated via long constructor + Condition cond2 = new Condition(longUri, longString, longString, longString, + -1, Condition.STATE_TRUE, Condition.SOURCE_CONTEXT, Condition.FLAG_RELEVANT_ALWAYS); + + assertThat(cond2.id.toString()).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(cond2.summary).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(cond2.line1).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(cond2.line2).hasLength(Condition.MAX_STRING_LENGTH); + } + + @Test + public void testLongFields_viaParcel() throws Exception { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + // Set fields via reflection to force them to be long, then parcel and unparcel to make sure + // it gets truncated upon unparcelling. + Condition cond = new Condition(Uri.parse("uri://placeholder"), "placeholder", + Condition.STATE_TRUE, Condition.SOURCE_CONTEXT); + + String longString = Strings.repeat("A", 65536); + Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530)); + Field id = Class.forName(CLASS).getDeclaredField("id"); + id.setAccessible(true); + id.set(cond, longUri); + Field summary = Class.forName(CLASS).getDeclaredField("summary"); + summary.setAccessible(true); + summary.set(cond, longString); + Field line1 = Class.forName(CLASS).getDeclaredField("line1"); + line1.setAccessible(true); + line1.set(cond, longString); + Field line2 = Class.forName(CLASS).getDeclaredField("line2"); + line2.setAccessible(true); + line2.set(cond, longString); + + Parcel parcel = Parcel.obtain(); + cond.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + Condition fromParcel = new Condition(parcel); + assertThat(fromParcel.id.toString()).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(fromParcel.summary).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(fromParcel.line1).hasLength(Condition.MAX_STRING_LENGTH); + assertThat(fromParcel.line2).hasLength(Condition.MAX_STRING_LENGTH); + } + + @Test + public void testEquals() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + + Condition cond1 = new Condition(Uri.parse("uri://placeholder"), "placeholder", + Condition.STATE_TRUE, Condition.SOURCE_USER_ACTION); + Condition cond2 = new Condition(Uri.parse("uri://placeholder"), "placeholder", + "", "", -1, + Condition.STATE_TRUE, Condition.SOURCE_SCHEDULE, Condition.FLAG_RELEVANT_ALWAYS); + + assertThat(cond1).isNotEqualTo(cond2); + Condition cond3 = new Condition(Uri.parse("uri://placeholder"), "placeholder", + Condition.STATE_TRUE, Condition.SOURCE_SCHEDULE); + assertThat(cond3).isEqualTo(cond2); + } + + @Test + public void testParcelConstructor() { + mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API); + + Condition cond = new Condition(Uri.parse("uri://placeholder"), "placeholder", + Condition.STATE_TRUE, Condition.SOURCE_USER_ACTION); + + Parcel parcel = Parcel.obtain(); + cond.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + Condition fromParcel = new Condition(parcel); + assertThat(fromParcel).isEqualTo(cond); + } } diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java index 9595332afc6c..e1bcd4a0727b 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.InsetsSource.ID_IME_CAPTION_BAR; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.LAST; import static android.view.WindowInsets.Type.SIZE; @@ -52,12 +53,15 @@ public class InsetsSourceTest { private final InsetsSource mSource = new InsetsSource(0 /* id */, navigationBars()); private final InsetsSource mImeSource = new InsetsSource(1 /* id */, ime()); + private final InsetsSource mImeCaptionSource = new InsetsSource( + ID_IME_CAPTION_BAR, captionBar()); private final InsetsSource mCaptionSource = new InsetsSource(2 /* id */, captionBar()); @Before public void setUp() { mSource.setVisible(true); mImeSource.setVisible(true); + mImeCaptionSource.setVisible(true); mCaptionSource.setVisible(true); } @@ -110,6 +114,18 @@ public class InsetsSourceTest { } @Test + public void testCalculateInsets_imeCaptionBar() { + mImeCaptionSource.setFrame(new Rect(0, 400, 500, 500)); + Insets insets = mImeCaptionSource.calculateInsets(new Rect(0, 0, 500, 500), false); + assertEquals(Insets.of(0, 0, 0, 100), insets); + + // Place caption bar at top; IME caption bar must always return bottom insets + mImeCaptionSource.setFrame(new Rect(0, 0, 500, 100)); + insets = mImeCaptionSource.calculateInsets(new Rect(0, 0, 500, 500), false); + assertEquals(Insets.of(0, 0, 0, 100), insets); + } + + @Test public void testCalculateInsets_caption_resizing() { mCaptionSource.setFrame(new Rect(0, 0, 100, 100)); Insets insets = mCaptionSource.calculateInsets(new Rect(0, 0, 200, 200), false); diff --git a/core/tests/coretests/src/com/android/internal/jank/DisplayRefreshRateTest.java b/core/tests/coretests/src/com/android/internal/jank/DisplayRefreshRateTest.java new file mode 100644 index 000000000000..725885a84873 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/jank/DisplayRefreshRateTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.jank; + +import static com.android.internal.jank.DisplayRefreshRate.REFRESH_RATE_120_HZ; +import static com.android.internal.jank.DisplayRefreshRate.REFRESH_RATE_240_HZ; +import static com.android.internal.jank.DisplayRefreshRate.REFRESH_RATE_30_HZ; +import static com.android.internal.jank.DisplayRefreshRate.REFRESH_RATE_60_HZ; +import static com.android.internal.jank.DisplayRefreshRate.REFRESH_RATE_90_HZ; +import static com.android.internal.jank.DisplayRefreshRate.getRefreshRate; + +import static com.google.common.truth.Truth.assertThat; + +import androidx.test.filters.SmallTest; + +import org.junit.Test; + +@SmallTest +public class DisplayRefreshRateTest { + @Test + public void testRefreshRateMapping() { + assertThat(getRefreshRate((long) 1e9 / 30)).isEqualTo(REFRESH_RATE_30_HZ); + assertThat(getRefreshRate((long) 1e9 / 60)).isEqualTo(REFRESH_RATE_60_HZ); + assertThat(getRefreshRate((long) 1e9 / 90)).isEqualTo(REFRESH_RATE_90_HZ); + assertThat(getRefreshRate((long) 1e9 / 120)).isEqualTo(REFRESH_RATE_120_HZ); + assertThat(getRefreshRate((long) 1e9 / 240)).isEqualTo(REFRESH_RATE_240_HZ); + } +} diff --git a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java index dbbd70525d28..1b9717a6dfc5 100644 --- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java +++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java @@ -70,6 +70,8 @@ import java.util.concurrent.TimeUnit; @SmallTest public class FrameTrackerTest { private static final String CUJ_POSTFIX = ""; + private static final long FRAME_TIME_60Hz = (long) 1e9 / 60; + private ViewAttachTestActivity mActivity; @Rule @@ -170,6 +172,7 @@ public class FrameTrackerTest { verify(tracker, never()).triggerPerfetto(); verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(0L) /* missedFrames */, @@ -207,6 +210,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(1L) /* missedFrames */, @@ -244,6 +248,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(0L) /* missedFrames */, @@ -281,6 +286,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(1L) /* missedFrames */, @@ -321,6 +327,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(1L) /* missedFrames */, @@ -363,6 +370,7 @@ public class FrameTrackerTest { verify(tracker, never()).triggerPerfetto(); verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE]), eq(2L) /* totalFrames */, eq(0L) /* missedFrames */, @@ -491,6 +499,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]), eq(2L) /* totalFrames */, eq(1L) /* missedFrames */, @@ -528,6 +537,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]), eq(2L) /* totalFrames */, eq(0L) /* missedFrames */, @@ -565,6 +575,7 @@ public class FrameTrackerTest { verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]), eq(2L) /* totalFrames */, eq(0L) /* missedFrames */, @@ -596,6 +607,7 @@ public class FrameTrackerTest { verify(tracker).triggerPerfetto(); verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED), eq(42), /* displayId */ + eq(DisplayRefreshRate.REFRESH_RATE_60_HZ), eq(CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_WALLPAPER_TRANSITION]), eq(6L) /* totalFrames */, eq(5L) /* missedFrames */, @@ -648,7 +660,7 @@ public class FrameTrackerTest { final ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class); doNothing().when(tracker).postCallback(captor.capture()); mListenerCapture.getValue().onJankDataAvailable(new JankData[] { - new JankData(vsyncId, jankType) + new JankData(vsyncId, jankType, FRAME_TIME_60Hz) }); captor.getValue().run(); } diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 3218666771df..1f08955e5f58 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -467,6 +467,7 @@ applications that come with the platform <permission name="android.permission.BIND_HOTWORD_DETECTION_SERVICE" /> <permission name="android.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE" /> <permission name="android.permission.MANAGE_APP_HIBERNATION"/> + <permission name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO" /> <!-- Permission required for CTS test - ResourceObserverNativeTest --> <permission name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" /> <!-- Permission required for CTS test - MediaCodecResourceTest --> diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index b7140355e489..231fa4837441 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -1282,15 +1282,18 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * function (MGF1) with a digest. * The default digest for MGF1 is {@code SHA-1}, which will be specified during key creation * time if no digests have been explicitly provided. - * When using the key, the caller may not specify any digests that were not provided during - * key creation time. The caller may specify the default digest, {@code SHA-1}, if no + * {@code null} may not be specified as a parameter to this method: It is not possible to + * disable MGF1 digest, a default must be present for when the caller tries to use it. + * + * <p>When using the key, the caller may not specify any digests that were not provided + * during key creation time. The caller may specify the default digest, {@code SHA-1}, if no * digests were explicitly provided during key creation (but it is not necessary to do so). * * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull @FlaggedApi("MGF1_DIGEST_SETTER") - public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { + public Builder setMgf1Digests(@NonNull @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; } diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 2471cbac0c84..90b13cdc79b4 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Laat los"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App sal dalk nie met verdeelde skerm werk nie"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App steun nie verdeelde skerm nie"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Hierdie app kan net in 1 venster oopgemaak word"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Program sal dalk nie op \'n sekondêre skerm werk nie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Program steun nie begin op sekondêre skerms nie."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Skermverdeler"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 387478c66267..478585aace68 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"መተግበሪያ ከተከፈለ ማያ ገፅ ጋር ላይሠራ ይችላል"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ይህ መተግበሪያ መከፈት የሚችለው በ1 መስኮት ብቻ ነው"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string> <string name="accessibility_divider" msgid="6407584574218956849">"የተከፈለ የማያ ገፅ ከፋይ"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index fb92ed7650de..b2a522c89f8c 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"إظهار"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"قد لا يعمل التطبيق بشكل سليم في وضع تقسيم الشاشة."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"لا يعمل التطبيق في وضع تقسيم الشاشة."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"لا يمكن فتح هذا التطبيق إلا في نافذة واحدة."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"قد لا يعمل التطبيق على شاشة عرض ثانوية."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"لا يمكن تشغيل التطبيق على شاشات عرض ثانوية."</string> <string name="accessibility_divider" msgid="6407584574218956849">"أداة تقسيم الشاشة"</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index 5e44e4723252..897c38f66e4b 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"দেখুৱাওক"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"এপ্টোৱে বিভাজিত স্ক্ৰীনৰ সৈতে কাম নকৰিব পাৰে"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"এপ্টোৱে বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"এই এপ্টো কেৱল ১ খন ৱিণ্ড’ত খুলিব পাৰি"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"গৌণ ডিছপ্লেত এপে সঠিকভাৱে কাম নকৰিব পাৰে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"গৌণ ডিছপ্লেত এপ্ লঞ্চ কৰিব নোৱাৰি।"</string> <string name="accessibility_divider" msgid="6407584574218956849">"স্প্লিট স্ক্ৰীনৰ বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index 4e2f9b98fba7..4854e0db7ed5 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Güvənli məkandan çıxarın"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Tətbiq bölünmüş ekranda işləməyə bilər"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Tətbiq bölünmüş ekranı dəstəkləmir"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Bu tətbiq yalnız 1 pəncərədə açıla bilər"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Tətbiq ikinci ekranda işləməyə bilər."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Tətbiq ikinci ekranda başlamağı dəstəkləmir."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Bölünmüş ekran ayırıcısı"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index 990aed8af763..cac4e67b1cfc 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Uklonite iz tajne memorije"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacija možda neće raditi sa podeljenim ekranom."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacija ne podržava podeljeni ekran."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ova aplikacija može da se otvori samo u jednom prozoru"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionisati na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Razdelnik podeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index febb0646968d..cac76df15910 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Паказаць"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Праграма можа не працаваць у рэжыме падзеленага экрана"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Праграма не падтрымлівае рэжым падзеленага экрана"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Гэту праграму можна адкрыць толькі ў адным акне"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Праграма можа не працаваць на дадатковых экранах."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Праграма не падтрымлівае запуск на дадатковых экранах."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Раздзяляльнік падзеленага экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 8bbdf9174458..ac9a20806b72 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Отмяна на съхраняването"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Приложението може да не работи в режим на разделен екран"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Приложението не поддържа разделен екран"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Това приложение може да се отвори само в 1 прозорец"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Възможно е приложението да не работи на алтернативни дисплеи."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложението не поддържа използването на алтернативни дисплеи."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Разделител в режима за разделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 4678b174685c..3b83dcb461ee 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"আনস্ট্যাস করুন"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"স্প্লিট স্ক্রিনে এই অ্যাপ নাও কাজ করতে পারে"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"স্প্লিট স্ক্রিনে এই অ্যাপ কাজ করে না"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"এই অ্যাপটি শুধুমাত্র ১টি উইন্ডোতে খোলা যেতে পারে"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"সেকেন্ডারি ডিসপ্লেতে অ্যাপটি কাজ নাও করতে পারে।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"সেকেন্ডারি ডিসপ্লেতে অ্যাপ লঞ্চ করা যাবে না।"</string> <string name="accessibility_divider" msgid="6407584574218956849">"স্প্লিট স্ক্রিন বিভাজক"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 076a17d4973e..813d163d07fe 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vađenje iz stasha"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacija možda neće funkcionirati na podijeljenom ekranu"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacija ne podržava podijeljeni ekran"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ova aplikacija se može otvoriti samo u 1 prozoru"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće raditi na sekundarnom ekranu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim ekranima."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Razdjelnik podijeljenog ekrana"</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 311599824779..d00c50bb0294 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Deixa d\'amagar"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"És possible que l\'aplicació no funcioni amb la pantalla dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'aplicació no admet la pantalla dividida"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Aquesta aplicació només pot obrir-se en 1 finestra"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"És possible que l\'aplicació no funcioni en una pantalla secundària."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'aplicació no es pot obrir en pantalles secundàries."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Separador de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index fe8a7eed7254..40132e4f67f8 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušit uložení"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikace v režimu rozdělené obrazovky nemusí fungovat"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikace nepodporuje režim rozdělené obrazovky"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Tuto aplikaci lze otevřít jen v jednom okně"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikace na sekundárním displeji nemusí fungovat."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikace nepodporuje spuštění na sekundárních displejích."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Čára rozdělující obrazovku"</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 81c5b228c159..6e9738dc7398 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Vis"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Appen fungerer muligvis ikke i opdelt skærm"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Appen understøtter ikke opdelt skærm"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Denne app kan kun åbnes i 1 vindue"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer muligvis ikke på sekundære skærme."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Adskiller til opdelt skærm"</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 4b9556d4515f..5da224d35360 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Aus Stash entfernen"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Die App funktioniert im Splitscreen-Modus unter Umständen nicht"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Splitscreen wird in dieser App nicht unterstützt"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Diese App kann nur in einem einzigen Fenster geöffnet werden"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Bildschirmteiler"</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 907ef38b5c3c..822b5526c6fd 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Κατάργηση απόκρυψης"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Η εφαρμογή ενδέχεται να μην λειτουργεί με διαχωρισμό οθόνης."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Αυτή η εφαρμογή μπορεί να ανοίξει μόνο σε ένα παράθυρο"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Η εφαρμογή ίσως να μην λειτουργήσει σε δευτερεύουσα οθόνη."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Η εφαρμογή δεν υποστηρίζει την εκκίνηση σε δευτερεύουσες οθόνες."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Διαχωριστικό οθόνης"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index 843c8ed3090b..76464b398f89 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App may not work with split screen"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App does not support split screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"This app can only be opened in one window"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index 0d9d09a0465f..c0c46cd608ee 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App may not work with split screen"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App does not support split screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"This app can only be opened in 1 window"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index 843c8ed3090b..76464b398f89 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App may not work with split screen"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App does not support split screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"This app can only be opened in one window"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index 843c8ed3090b..76464b398f89 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App may not work with split screen"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App does not support split screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"This app can only be opened in one window"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 4fbb5b830f29..f089938fd9cb 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"App may not work with split screen"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App does not support split screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"This app can only be opened in 1 window"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App may not work on a secondary display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App does not support launch on secondary displays."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Split screen divider"</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index 9aa985d21819..6bbc1e37671f 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Dejar de almacenar de manera segura"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Es posible que la app no funcione en el modo de pantalla dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"La app no es compatible con la función de pantalla dividida"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esta app solo puede estar abierta en 1 ventana"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la app no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La app no puede iniciarse en pantallas secundarias."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index e51f73541f5f..c662ff603dd7 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"No esconder"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Puede que la aplicación no funcione con la pantalla dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"La aplicación no es compatible con la pantalla dividida"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esta aplicación solo puede abrirse en una ventana"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Es posible que la aplicación no funcione en una pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"La aplicación no se puede abrir en pantallas secundarias."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index b3f30e76cd81..ade5e2d18645 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Eemalda hoidlast"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Rakendus ei pruugi jagatud ekraanikuvaga töötada."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Rakendus ei toeta jagatud ekraanikuva."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Selle rakenduse saab avada ainult ühes aknas"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Rakendus ei pruugi teisesel ekraanil töötada."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Rakendus ei toeta teisestel ekraanidel käivitamist."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Jagatud ekraanikuva jaotur"</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 0d9d70637107..d6cb66885cf5 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ez gorde"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Baliteke aplikazioak ez funtzionatzea pantaila zatituan"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikazioak ez du onartzen pantaila zatitua"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Leiho bakar batean ireki daiteke aplikazioa"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Baliteke aplikazioak ez funtzionatzea bigarren mailako pantailetan."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikazioa ezin da exekutatu bigarren mailako pantailatan."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Pantaila-zatitzailea"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 267daaabbb2c..ba0f51cb1490 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"لغو مخفیسازی"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ممکن است برنامه با صفحهٔ دونیمه کار نکند"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"برنامه از صفحهٔ دونیمه پشتیبانی نمیکند"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"این برنامه فقط در ۱ پنجره میتواند باز شود"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن است برنامه در نمایشگر ثانویه کار نکند."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"برنامه از راهاندازی در نمایشگرهای ثانویه پشتیبانی نمیکند."</string> <string name="accessibility_divider" msgid="6407584574218956849">"تقسیمکننده صفحهٔ دونیمه"</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index 7be7557323ca..a53f861e1d18 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poista turvasäilytyksestä"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Sovellus ei ehkä toimi jaetulla näytöllä"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Sovellus ei tue jaetun näytön tilaa"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Tämän sovelluksen voi avata vain yhdessä ikkunassa"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Sovellus ei ehkä toimi toissijaisella näytöllä."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Sovellus ei tue käynnistämistä toissijaisilla näytöillä."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Näytönjakaja"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 5cee03786bdc..4563556657af 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Retirer de la réserve"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'application peut ne pas fonctionner avec l\'écran partagé"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'application ne prend pas en charge l\'écran partagé"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette application ne peut être ouverte que dans une seule fenêtre."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index 0b3b364202cf..895757184b23 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'appli peut ne pas fonctionner en mode Écran partagé"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Appli incompatible avec l\'écran partagé"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette appli ne peut être ouverte que dans 1 fenêtre"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'application ne fonctionne pas sur un écran secondaire."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'application ne peut pas être lancée sur des écrans secondaires."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Séparateur d\'écran partagé"</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index a46c9e74a178..54c864eced47 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Non esconder"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"É posible que a aplicación non funcione coa pantalla dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"A aplicación non admite a función de pantalla dividida"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esta aplicación só se pode abrir en 1 ventá"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É posible que a aplicación non funcione nunha pantalla secundaria."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A aplicación non se pode iniciar en pantallas secundarias."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor de pantalla dividida"</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index ad27a79e21a4..2b092795b035 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"બતાવો"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"વિભાજિત સ્ક્રીન સાથે ઍપ કદાચ કામ ન કરે"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ઍપ વિભાજિત સ્ક્રીનને સપોર્ટ કરતી નથી"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"આ ઍપ માત્ર 1 વિન્ડોમાં ખોલી શકાય છે"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર કદાચ કામ ન કરે."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ઍપ્લિકેશન ગૌણ ડિસ્પ્લે પર લૉન્ચનું સમર્થન કરતી નથી."</string> <string name="accessibility_divider" msgid="6407584574218956849">"સ્ક્રીનને વિભાજિત કરતું વિભાજક"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 9b10fdcf07a0..35b099ac6d38 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"दिखाएं"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"मुमकिन है कि ऐप्लिकेशन, स्प्लिट स्क्रीन मोड में काम न करे"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"यह ऐप्लिकेशन, स्प्लिट स्क्रीन मोड पर काम नहीं करता"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"इस ऐप्लिकेशन को सिर्फ़ एक विंडो में खोला जा सकता है"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"हो सकता है कि ऐप प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर काम न करे."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"प्राइमरी (मुख्य) डिस्प्ले के अलावा बाकी दूसरे डिस्प्ले पर ऐप लॉन्च नहीं किया जा सकता."</string> <string name="accessibility_divider" msgid="6407584574218956849">"स्प्लिट स्क्रीन डिवाइडर मोड"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index ae4ff2d95a50..f2c3c22414df 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Poništite sakrivanje"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacija možda neće funkcionirati s podijeljenim zaslonom"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacija ne podržava podijeljeni zaslon"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ova se aplikacija može otvoriti samo u jednom prozoru"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija možda neće funkcionirati na sekundarnom zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podržava pokretanje na sekundarnim zaslonima."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Razdjelnik podijeljenog zaslona"</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index 070743c46fa9..d94bb29f1d73 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Félretevés megszüntetése"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Lehet, hogy az alkalmazás nem működik osztott képernyős nézetben"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Az alkalmazás nem támogatja az osztott képernyőt"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ez az alkalmazás csak egy ablakban nyitható meg"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Előfordulhat, hogy az alkalmazás nem működik másodlagos kijelzőn."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Az alkalmazást nem lehet másodlagos kijelzőn elindítani."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Elválasztó az osztott képernyős nézetben"</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index dfdc97479743..f2945c16e50b 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ցուցադրել"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Հավելվածը չի կարող աշխատել տրոհված էկրանի ռեժիմում"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Հավելվածը չի աջակցում էկրանի տրոհումը"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Այս հավելվածը հնարավոր է բացել միայն մեկ պատուհանում"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Հավելվածը կարող է չաշխատել լրացուցիչ էկրանի վրա"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Հավելվածը չի աջակցում գործարկումը լրացուցիչ էկրանների վրա"</string> <string name="accessibility_divider" msgid="6407584574218956849">"Տրոհված էկրանի բաժանիչ"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index f6161a9d0afd..c39b429e489c 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Batalkan stash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikasi mungkin tidak berfungsi dengan layar terpisah"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikasi tidak mendukung layar terpisah"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Aplikasi ini hanya dapat dibuka di 1 jendela"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikasi mungkin tidak berfungsi pada layar sekunder."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikasi tidak mendukung peluncuran pada layar sekunder."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Pembagi layar terpisah"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 0cc1006da65e..630eaa3855c1 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Taka úr geymslu"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Forritið virkar hugsanlega ekki með skjáskiptingu"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Forritið styður ekki skjáskiptingu"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Aðeins er hægt að opna þetta forrit í 1 glugga"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Hugsanlegt er að forritið virki ekki á öðrum skjá."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Forrit styður ekki opnun á öðrum skjá."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Skilrúm skjáskiptingar"</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index bddde703bc80..77893c9e38cf 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Annulla accantonamento"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'app potrebbe non funzionare con lo schermo diviso"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'app non supporta la modalità schermo diviso"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Questa app può essere aperta soltanto in 1 finestra"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"L\'app potrebbe non funzionare su un display secondario."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'app non supporta l\'avvio su display secondari."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Strumento per schermo diviso"</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 32b75ec9cba7..4f28c23ba5df 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ביטול ההסתרה הזמנית"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"יכול להיות שהאפליקציה לא תפעל עם מסך מפוצל"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"האפליקציה לא תומכת במסך מפוצל"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ניתן לפתוח את האפליקציה הזו רק בחלון אחד"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ייתכן שהאפליקציה לא תפעל במסך משני."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"האפליקציה אינה תומכת בהפעלה במסכים משניים."</string> <string name="accessibility_divider" msgid="6407584574218956849">"מחלק מסך מפוצל"</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index ea19f5ac2d1e..60b4d7eb8b4d 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"表示"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"アプリは分割画面では動作しないことがあります"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"アプリで分割画面がサポートされていません"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"このアプリはウィンドウが 1 つの場合のみ開くことができます"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"アプリはセカンダリ ディスプレイでは動作しないことがあります。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"アプリはセカンダリ ディスプレイでの起動に対応していません。"</string> <string name="accessibility_divider" msgid="6407584574218956849">"分割画面の分割線"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 1a4d17c73a32..28d2257786a7 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"გადანახვის გაუქმება"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"აპმა შეიძლება არ იმუშაოს გაყოფილი ეკრანის რეჟიმში"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ამ აპის გახსნა შესაძლებელია მხოლოდ 1 ფანჯარაში"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"აპმა შეიძლება არ იმუშაოს მეორეულ ეკრანზე."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"აპს არ გააჩნია მეორეული ეკრანის მხარდაჭერა."</string> <string name="accessibility_divider" msgid="6407584574218956849">"ეკრანის გაყოფის გამყოფი"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 4d5ac830ce8a..441df8d70e95 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Көрсету"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Қолданба экранды бөлу режимінде жұмыс істемеуі мүмкін."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Қолданбада экранды бөлу мүмкін емес."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Бұл қолданбаны тек 1 терезеден ашуға болады."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Қолданба қосымша дисплейде жұмыс істемеуі мүмкін."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Қолданба қосымша дисплейлерде іске қосуды қолдамайды."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Экранды бөлу режимінің бөлгіші"</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index f90ca9a1bcaf..efa6418eaa47 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ឈប់លាក់ជាបណ្ដោះអាសន្ន"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"កម្មវិធីអាចមិនដំណើរការជាមួយមុខងារបំបែកអេក្រង់ទេ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"កម្មវិធីមិនអាចប្រើមុខងារបំបែកអេក្រង់បានទេ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"អាចបើកកម្មវិធីនេះបានតែក្នុងវិនដូ 1 ប៉ុណ្ណោះ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"កម្មវិធីនេះប្រហែលជាមិនដំណើរការនៅលើអេក្រង់បន្ទាប់បន្សំទេ។"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"កម្មវិធីនេះមិនអាចចាប់ផ្តើមនៅលើអេក្រង់បន្ទាប់បន្សំបានទេ។"</string> <string name="accessibility_divider" msgid="6407584574218956849">"បន្ទាត់ខណ្ឌចែកក្នុងមុខងារបំបែកអេក្រង់"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 57aa771a2548..0cda44509b54 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ಅನ್ಸ್ಟ್ಯಾಶ್ ಮಾಡಿ"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಆ್ಯಪ್ ಕೆಲಸ ಮಾಡದೇ ಇರಬಹುದು"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆ್ಯಪ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ಈ ಆ್ಯಪ್ ಅನ್ನು 1 ವಿಂಡೋದಲ್ಲಿ ಮಾತ್ರ ತೆರೆಯಬಹುದು"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಾರ್ಯ ನಿರ್ವಹಿಸದೇ ಇರಬಹುದು."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ಸೆಕೆಂಡರಿ ಡಿಸ್ಪ್ಲೇಗಳಲ್ಲಿ ಪ್ರಾರಂಭಿಸುವಿಕೆಯನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string> <string name="accessibility_divider" msgid="6407584574218956849">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಡಿವೈಡರ್"</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index e777fa7dc7a0..676506fc68dd 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"숨기기 취소"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"앱이 화면 분할 모드로는 작동하지 않을 수 있습니다"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"앱이 화면 분할을 지원하지 않습니다"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"이 앱은 창 1개에서만 열 수 있습니다."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"앱이 보조 디스플레이에서 작동하지 않을 수도 있습니다."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"앱이 보조 디스플레이에서의 실행을 지원하지 않습니다."</string> <string name="accessibility_divider" msgid="6407584574218956849">"화면 분할기"</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index a96f3c8eb87a..57253ef55085 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Сейфтен чыгаруу"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Колдонмодо экран бөлүнбөшү мүмкүн"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Колдонмодо экран бөлүнбөйт"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Бул колдонмону 1 терезеде гана ачууга болот"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Колдонмо кошумча экранда иштебей коюшу мүмкүн."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Колдонмону кошумча экрандарда иштетүүгө болбойт."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Экранды бөлгүч"</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 6ab04c596cd3..c5f6e2245b31 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ເອົາອອກຈາກບ່ອນເກັບສ່ວນຕົວ"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ແອັບອາດໃຊ້ບໍ່ໄດ້ກັບໂໝດແບ່ງໜ້າຈໍ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ແອັບບໍ່ຮອງຮັບການແບ່ງໜ້າຈໍ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ແອັບນີ້ສາມາດເປີດໄດ້ໃນ 1 ໜ້າຈໍເທົ່ານັ້ນ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ແອັບອາດບໍ່ສາມາດໃຊ້ໄດ້ໃນໜ້າຈໍທີສອງ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ແອັບບໍ່ຮອງຮັບການເປີດໃນໜ້າຈໍທີສອງ."</string> <string name="accessibility_divider" msgid="6407584574218956849">"ເສັ້ນແບ່ງໜ້າຈໍ"</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index 9ef541e91c5b..eeed5a416fdc 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Nebeslėpti"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Programa gali neveikti naudojant išskaidyto ekrano režimą"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Programoje nepalaikomas išskaidyto ekrano režimas"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Šią programą galima atidaryti tik viename lange"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Programa gali neveikti antriniame ekrane."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programa nepalaiko paleisties antriniuose ekranuose."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Išskaidyto ekrano režimo daliklis"</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index 634db045b754..4324d468042b 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Rādīt"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Iespējams, lietotne nedarbosies ekrāna sadalīšanas režīmā"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Lietotnē netiek atbalstīta ekrāna sadalīšana"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Šo lietotni var atvērt tikai vienā logā"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Lietotne, iespējams, nedarbosies sekundārajā displejā."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Lietotnē netiek atbalstīta palaišana sekundārajos displejos."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Ekrāna sadalītājs"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 6272b05ea768..471f5bdfcf1a 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Прикажете"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Апликацијата можеби нема да работи со поделен екран"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Апликацијата не поддржува поделен екран"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Апликацијава може да се отвори само во еден прозорец"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликацијата може да не функционира на друг екран."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликацијата не поддржува стартување на други екрани."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Разделник на поделен екран"</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index dcc12a752f31..5bc694a10747 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"അൺസ്റ്റാഷ് ചെയ്യൽ"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"സ്ക്രീൻ വിഭജന മോഡിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"സ്ക്രീൻ വിഭജന മോഡിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ഈ ആപ്പ് ഒരു വിൻഡോയിൽ മാത്രമേ തുറക്കാനാകൂ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"രണ്ടാം ഡിസ്പ്ലേയിൽ ആപ്പ് പ്രവർത്തിച്ചേക്കില്ല."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"രണ്ടാം ഡിസ്പ്ലേകളിൽ സമാരംഭിക്കുന്നതിനെ ആപ്പ് അനുവദിക്കുന്നില്ല."</string> <string name="accessibility_divider" msgid="6407584574218956849">"സ്ക്രീൻ വിഭജന മോഡ് ഡിവൈഡർ"</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index 5ff9c97d3432..0268c649380d 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Ил гаргах"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Апп дэлгэцийг хуваах горимтой ажиллахгүй байж магадгүй"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Апп дэлгэцийг хуваах горимыг дэмждэггүй"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Энэ аппыг зөвхөн 1 цонхонд нээх боломжтой"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апп хоёрдогч дэлгэцэд ажиллахгүй."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Аппыг хоёрдогч дэлгэцэд эхлүүлэх боломжгүй."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Дэлгэцийг хуваах хуваагч"</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index 1dc4151e506f..2e6163e65668 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्टॅश करा"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"अॅप कदाचित स्प्लिट स्क्रीनसह काम करणार नाही"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"अॅप हे स्प्लिट स्क्रीनला सपोर्ट करत नाही"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"हे अॅप फक्त एका विंडोमध्ये उघडले जाऊ शकते"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"दुसऱ्या डिस्प्लेवर अॅप कदाचित चालणार नाही."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"दुसऱ्या डिस्प्लेवर अॅप लाँच होणार नाही."</string> <string name="accessibility_divider" msgid="6407584574218956849">"स्प्लिट स्क्रीन विभाजक"</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index c20f2b19afa1..a60e61b892cb 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Tunjukkan"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Apl mungkin tidak berfungsi dengan skrin pisah"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Apl tidak menyokong skrin pisah"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Apl ini hanya boleh dibuka dalam 1 tetingkap"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Apl mungkin tidak berfungsi pada paparan kedua."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Apl tidak menyokong pelancaran pada paparan kedua."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Pembahagi skrin pisah"</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index c07511bde9f9..6b91d4676621 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"မသိုဝှက်ရန်"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းဖြင့် အက်ပ်သည် အလုပ်မလုပ်ပါ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"အက်ပ်တွင် မျက်နှာပြင် ခွဲ၍ပြသခြင်းကို မပံ့ပိုးပါ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ဤအက်ပ်ကို ဝင်းဒိုး ၁ ခုတွင်သာ ဖွင့်နိုင်သည်"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ဤအက်ပ်အနေဖြင့် ဒုတိယဖန်သားပြင်ပေါ်တွင် အလုပ်လုပ်မည် မဟုတ်ပါ။"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ဤအက်ပ်အနေဖြင့် ဖွင့်ရန်စနစ်ကို ဒုတိယဖန်သားပြင်မှ အသုံးပြုရန် ပံ့ပိုးမထားပါ။"</string> <string name="accessibility_divider" msgid="6407584574218956849">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း ပိုင်းခြားစနစ်"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 458487c35d63..ec9ece3484b8 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Avslutt oppbevaring"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Det kan hende at appen ikke fungerer med delt skjerm"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Appen støtter ikke delt skjerm"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Denne appen kan bare åpnes i ett vindu"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen fungerer kanskje ikke på en sekundær skjerm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan ikke kjøres på sekundære skjermer."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Skilleelement for delt skjerm"</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index 09d8396eed59..8bb07be12c48 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"अनस्ट्यास गर्नुहोस्"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"यो एपले स्प्लिट स्क्रिन मोडमा काम नगर्न सक्छ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"यो एप स्प्लिट स्क्रिन मोडमा प्रयोग गर्न मिल्दैन"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"यो एप एउटा विन्डोमा मात्र खोल्न मिल्छ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"यो एपले सहायक प्रदर्शनमा काम नगर्नसक्छ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"अनुप्रयोगले सहायक प्रदर्शनहरूमा लञ्च सुविधालाई समर्थन गर्दैन।"</string> <string name="accessibility_divider" msgid="6407584574218956849">"स्प्लिट स्क्रिन डिभाइडर"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index 8b91fa299847..c6c60ae4b1f2 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Niet meer verbergen"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"De app werkt misschien niet met gesplitst scherm"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"App ondersteunt geen gesplitst scherm"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Deze app kan maar in 1 venster worden geopend"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"App werkt mogelijk niet op een secundair scherm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"App kan niet op secundaire displays worden gestart."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Scheiding voor gesplitst scherm"</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index de1c9983fac9..927dde40134d 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ଦେଖାନ୍ତୁ"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରେ ଆପ କାମ କରିନପାରେ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ଆପ ସମର୍ଥନ କରେ ନାହିଁ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ଏହି ଆପକୁ କେବଳ 1ଟି ୱିଣ୍ଡୋରେ ଖୋଲାଯାଇପାରିବ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ କାମ ନକରିପାରେ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ସେକେଣ୍ଡାରୀ ଡିସପ୍ଲେରେ ଆପ୍ ଲଞ୍ଚ ସପୋର୍ଟ କରେ ନାହିଁ।"</string> <string name="accessibility_divider" msgid="6407584574218956849">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ଡିଭାଇଡର"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 2a700d375961..0e12fb872005 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ਅਣਸਟੈਸ਼"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ਐਪ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ਇਹ ਐਪ ਸਿਰਫ਼ 1 ਵਿੰਡੋ ਵਿੱਚ ਖੋਲ੍ਹੀ ਜਾ ਸਕਦੀ ਹੈ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇ \'ਤੇ ਕੰਮ ਨਾ ਕਰੇ।"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ਐਪ ਸੈਕੰਡਰੀ ਡਿਸਪਲੇਆਂ \'ਤੇ ਲਾਂਚ ਕਰਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string> <string name="accessibility_divider" msgid="6407584574218956849">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿਭਾਜਕ"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 43cfa6461cc8..75a8ce6bc16d 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zabierz ze schowka"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacja może nie działać przy podzielonym ekranie"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacja nie obsługuje podzielonego ekranu"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ta aplikacja może być otwarta tylko w 1 oknie."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacja może nie działać na dodatkowym ekranie."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacja nie obsługuje uruchamiania na dodatkowych ekranach."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Linia dzielenia ekranu"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index fb1ef6880dc9..b84a0ded4939 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"É possível que o app não funcione com a tela dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"O app não oferece suporte à divisão de tela"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esse app só pode ser aberto em uma única janela"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 702c0433fa0a..d84bfcdd73ff 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Remover do armazenamento"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"A app pode não funcionar com o ecrã dividido"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"A app não é compatível com o ecrã dividido"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esta app só pode ser aberta em 1 janela"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"A app pode não funcionar num ecrã secundário."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"A app não é compatível com o início em ecrãs secundários."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor do ecrã dividido"</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index fb1ef6880dc9..b84a0ded4939 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Exibir"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"É possível que o app não funcione com a tela dividida"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"O app não oferece suporte à divisão de tela"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Esse app só pode ser aberto em uma única janela"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"É possível que o app não funcione em uma tela secundária."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"O app não é compatível com a inicialização em telas secundárias."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divisor de tela"</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 596eebc7dd95..eeea428cc8fa 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Anulează stocarea"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Este posibil ca aplicația să nu funcționeze cu ecranul împărțit"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplicația nu acceptă ecranul împărțit"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Aplicația se poate deschide într-o singură fereastră"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Este posibil ca aplicația să nu funcționeze pe un ecran secundar."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplicația nu acceptă lansare pe ecrane secundare."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Separator pentru ecranul împărțit"</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index f2f1f6fdd857..26b0f94eb585 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показать"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Когда включено разделение экрана, приложение может работать нестабильно."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Приложение не поддерживает разделение экрана."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Это приложение можно открыть только в одном окне."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Приложение может не работать на дополнительном экране"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Приложение не поддерживает запуск на дополнительных экранах"</string> <string name="accessibility_divider" msgid="6407584574218956849">"Разделитель экрана"</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index 0a1fd94a8998..9b9a430ce73f 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"සඟවා තැබීම ඉවත් කරන්න"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"යෙදුම බෙදීම් තිරය සමග ක්රියා නොකළ හැක"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"යෙදුම බෙදුම් තිරයට සහාය නොදක්වයි"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"මෙම යෙදුම විවෘත කළ හැක්කේ 1 කවුළුවක පමණයි"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"යෙදුම ද්විතියික සංදර්ශකයක ක්රියා නොකළ හැකිය."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"යෙදුම ද්විතීයික සංදර්ශක මත දියත් කිරීම සඳහා සහාය නොදක්වයි."</string> <string name="accessibility_divider" msgid="6407584574218956849">"බෙදුම් තිර වෙන්කරණය"</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index 6e746b01f2c3..4b2153180cbe 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Zrušiť skrytie"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikácia nemusí fungovať s rozdelenou obrazovkou"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikácia nepodporuje rozdelenú obrazovku"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Táto aplikácia môže byť otvorená iba v jednom okne"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikácia nemusí fungovať na sekundárnej obrazovke."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikácia nepodporuje spúšťanie na sekundárnych obrazovkách."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Rozdeľovač obrazovky"</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index 9536e05ef057..581cf5b815c6 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Razkrij"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacija morda ne deluje v načinu razdeljenega zaslona."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacija ne podpira načina razdeljenega zaslona."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"To aplikacijo je mogoče odpreti samo v enem oknu"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacija morda ne bo delovala na sekundarnem zaslonu."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacija ne podpira zagona na sekundarnih zaslonih."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Razdelilnik zaslonov"</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index a0fff68554e7..9dc7b7ebef99 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Mos e fshih"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Aplikacioni mund të mos funksionojë me ekranin e ndarë"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Aplikacioni nuk mbështet ekranin e ndarë"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ky aplikacion mund të hapet vetëm në 1 dritare"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Aplikacioni mund të mos funksionojë në një ekran dytësor."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Aplikacioni nuk mbështet nisjen në ekrane dytësore."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Ndarësi i ekranit të ndarë"</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index ad9ba9038eb8..cd532f79dd78 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Уклоните из тајне меморије"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Апликација можда неће радити са подељеним екраном."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Апликација не подржава подељени екран."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ова апликација може да се отвори само у једном прозору"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Апликација можда неће функционисати на секундарном екрану."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Апликација не подржава покретање на секундарним екранима."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Разделник подељеног екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 488af391b45b..386dda7e088d 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Återställ stash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Appen kanske inte fungerar med delad skärm"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Appen har inte stöd för delad skärm"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Denna app kan bara vara öppen i ett fönster"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Appen kanske inte fungerar på en sekundär skärm."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Appen kan inte köras på en sekundär skärm."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Avdelare för delad skärm"</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 38cbfe38007c..69b2e34ada3c 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Fichua"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Huenda programu isifanye kazi kwenye skrini iliyogawanywa"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Programu haifanyi kazi kwenye skrini iliyogawanywa"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Programu hii inaweza kufunguliwa katika dirisha 1 pekee"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Huenda programu isifanye kazi kwenye dirisha lingine."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Programu hii haiwezi kufunguliwa kwenye madirisha mengine."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Kitenganishi cha kugawa skrini"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 616aa274fa15..037b5aba22f5 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"திரைப் பிரிப்புப் பயன்முறையில் ஆப்ஸ் செயல்படாமல் போகக்கூடும்"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"திரைப் பிரிப்புப் பயன்முறையை ஆப்ஸ் ஆதரிக்காது"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"இந்த ஆப்ஸை 1 சாளரத்தில் மட்டுமே திறக்க முடியும்"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"இரண்டாம்நிலைத் திரையில் ஆப்ஸ் வேலை செய்யாமல் போகக்கூடும்."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"இரண்டாம்நிலைத் திரைகளில் பயன்பாட்டைத் தொடங்க முடியாது."</string> <string name="accessibility_divider" msgid="6407584574218956849">"திரைப் பிரிப்பான்"</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 6fe1995692ec..694ecb951210 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"ఆన్స్టాచ్"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"స్ప్లిట్ స్క్రీన్తో యాప్ పని చేయకపోవచ్చు"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"యాప్లో స్ప్లిట్ స్క్రీన్కు సపోర్ట్ లేదు"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"ఈ యాప్ను 1 విండోలో మాత్రమే తెరవవచ్చు"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ప్రత్యామ్నాయ డిస్ప్లేలో యాప్ పని చేయకపోవచ్చు."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ప్రత్యామ్నాయ డిస్ప్లేల్లో ప్రారంభానికి యాప్ మద్దతు లేదు."</string> <string name="accessibility_divider" msgid="6407584574218956849">"స్ప్లిట్ స్క్రీన్ డివైడర్"</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index 65e5ff77f6a6..d4b6aff2ee7d 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"เอาออกจากที่เก็บส่วนตัว"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"แอปอาจใช้ไม่ได้กับโหมดแยกหน้าจอ"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"แอปไม่รองรับการแยกหน้าจอ"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"แอปนี้เปิดได้ใน 1 หน้าต่างเท่านั้น"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"แอปอาจไม่ทำงานในจอแสดงผลรอง"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"แอปไม่รองรับการเรียกใช้ในจอแสดงผลรอง"</string> <string name="accessibility_divider" msgid="6407584574218956849">"เส้นแยกหน้าจอ"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index 74e0abee6732..db9303c0fd9c 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"I-unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Posibleng hindi gumana sa split screen ang app"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Hindi sinusuportahan ng app ang split-screen"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Sa 1 window lang puwedeng buksan ang app na ito"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Maaaring hindi gumana ang app sa pangalawang display."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Hindi sinusuportahan ng app ang paglulunsad sa mga pangalawang display."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Divider ng split screen"</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 2d169240afa8..818666c79973 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Depolama"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Uygulama bölünmüş ekranda çalışmayabilir"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Uygulama bölünmüş ekranı desteklemiyor."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Bu uygulama yalnızca 1 pencerede açılabilir"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uygulama ikincil ekranda çalışmayabilir."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uygulama ikincil ekranlarda başlatılmayı desteklemiyor."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Bölünmüş ekran ayırıcı"</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index 01031281818b..85fb8e114476 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Показати"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Додаток може не працювати в режимі розділення екрана"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Додаток не підтримує розділення екрана"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Цей додаток можна відкрити лише в одному вікні"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Додаток може не працювати на додатковому екрані."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Додаток не підтримує запуск на додаткових екранах."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Розділювач екрана"</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index 2fdcfe8015cf..813870b134b4 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"ممکن ہے کہ ایپ اسپلٹ اسکرین کے ساتھ کام نہ کرے"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"ایپ اسپلٹ اسکرین کو سپورٹ نہیں کرتی ہے"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"یہ ایپ صرف 1 ونڈو میں کھولی جا سکتی ہے"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"ممکن ہے ایپ ثانوی ڈسپلے پر کام نہ کرے۔"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"ایپ ثانوی ڈسپلیز پر شروعات کا تعاون نہیں کرتی۔"</string> <string name="accessibility_divider" msgid="6407584574218956849">"اسپلٹ اسکرین ڈیوائیڈر"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index a0d7cb6d228c..7bcacbb93f1f 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Chiqarish"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Bu ilovada ekranni ikkiga ajratish rejimi ishlamaydi."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Bu ilovada ekranni ikkiga ajratish ishlamaydi."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Bu ilovani faqat 1 ta oynada ochish mumkin"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Bu ilova qo‘shimcha ekranda ishlamasligi mumkin."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Bu ilova qo‘shimcha ekranlarda ishga tushmaydi."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Ekranni ikkiga ajratish chizigʻi"</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 957a4577430b..416dd91162c2 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Hiện"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Có thể ứng dụng không dùng được chế độ chia đôi màn hình"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Ứng dụng không hỗ trợ chế độ chia đôi màn hình"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Ứng dụng này chỉ có thể mở trong 1 cửa sổ"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Ứng dụng có thể không hoạt động trên màn hình phụ."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Ứng dụng không hỗ trợ khởi chạy trên màn hình phụ."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Trình chia đôi màn hình"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index e4bf0765ef06..6ad172807f6a 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消隐藏"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"应用可能无法在分屏模式下正常运行"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"应用不支持分屏"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"此应用只能在 1 个窗口中打开"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"应用可能无法在辅显示屏上正常运行。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"应用不支持在辅显示屏上启动。"</string> <string name="accessibility_divider" msgid="6407584574218956849">"分屏分隔线"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 20076211d2b6..b5b94ec40fd1 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消保護"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"應用程式可能無法在分割螢幕中運作"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"應用程式不支援分割螢幕"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"此應用程式只可在 1 個視窗中開啟"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示屏上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示屏上啟動。"</string> <string name="accessibility_divider" msgid="6407584574218956849">"分割螢幕分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index 1d69edd8b421..0f2a052dbbe0 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"取消暫時隱藏"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"應用程式可能無法在分割畫面中運作"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"這個應用程式不支援分割畫面"</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"這個應用程式只能在 1 個視窗中開啟"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"應用程式可能無法在次要顯示器上運作。"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"應用程式無法在次要顯示器上啟動。"</string> <string name="accessibility_divider" msgid="6407584574218956849">"分割畫面分隔線"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index 099879bca415..a696f9ec6251 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -34,8 +34,7 @@ <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Susa isiteshi"</string> <string name="dock_forced_resizable" msgid="7429086980048964687">"Ama-app okungenzeka angasebenzi ngesikrini esihlukanisiwe"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"I-app ayisekeli isikrini esihlukanisiwe."</string> - <!-- no translation found for dock_multi_instances_not_supported_text (5011042177901502928) --> - <skip /> + <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Le-app ingavulwa kuphela ewindini eli-1."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Uhlelo lokusebenza kungenzeka lungasebenzi kusibonisi sesibili."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Uhlelo lokusebenza alusekeli ukuqalisa kuzibonisi zesibili."</string> <string name="accessibility_divider" msgid="6407584574218956849">"Isihlukanisi sokuhlukanisa isikrini"</string> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java index 6cd1324c7d24..efa5a1a64ade 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java @@ -21,6 +21,7 @@ import static android.app.ActivityOptions.ANIM_CUSTOM; import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; +import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionTypeFromInfo; import android.annotation.NonNull; import android.annotation.Nullable; @@ -253,7 +254,8 @@ class ActivityEmbeddingAnimationSpec { private boolean shouldShowBackdrop(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change) { - final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE, + final int type = getTransitionTypeFromInfo(info); + final Animation a = loadAttributeAnimation(type, info, change, WALLPAPER_TRANSITION_NONE, mTransitionAnimation, false); return a != null && a.getShowBackdrop(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index f0da35df39ee..3e113276027e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -553,8 +553,9 @@ public class BubbleController implements ConfigurationChangeListener, * Hides the current input method, wherever it may be focused, via InputMethodManagerInternal. */ void hideCurrentInputMethod() { + int displayId = mWindowManager.getDefaultDisplay().getDisplayId(); try { - mBarService.hideCurrentInputMethodForBubbles(); + mBarService.hideCurrentInputMethodForBubbles(displayId); } catch (RemoteException e) { e.printStackTrace(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java index e9344ffcce0c..1c74f415ec90 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java @@ -322,13 +322,12 @@ public class SystemWindows { } @Override - public void remove(android.view.IWindow window) throws RemoteException { - super.remove(window); + public void remove(IBinder clientToken) throws RemoteException { + super.remove(clientToken); synchronized(this) { - IBinder token = window.asBinder(); - new SurfaceControl.Transaction().remove(mLeashForWindow.get(token)) + new SurfaceControl.Transaction().remove(mLeashForWindow.get(clientToken)) .apply(); - mLeashForWindow.remove(token); + mLeashForWindow.remove(clientToken); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java index 9bb383f0b61a..0448d94669ce 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java @@ -57,11 +57,6 @@ public class PipScheduler { @Nullable private SurfaceControl mPinnedTaskLeash; - // the leash of the original task of the PiP activity; - // used to synchronize app drawings in the multi-activity case - @Nullable - private SurfaceControl mOriginalTaskLeash; - /** * A temporary broadcast receiver to initiate exit PiP via expand. * This will later be modified to be triggered by the PiP menu. @@ -95,10 +90,6 @@ public class PipScheduler { mPinnedTaskLeash = pinnedTaskLeash; } - void setOriginalTaskLeash(SurfaceControl originalTaskLeash) { - mOriginalTaskLeash = originalTaskLeash; - } - void setPipTaskToken(@Nullable WindowContainerToken pipTaskToken) { mPipTaskToken = pipTaskToken; } @@ -133,6 +124,5 @@ public class PipScheduler { void onExitPip() { mPipTaskToken = null; mPinnedTaskLeash = null; - mOriginalTaskLeash = null; } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java index 7d3bd658d126..6200ea583a48 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java @@ -16,7 +16,6 @@ package com.android.wm.shell.pip2.phone; -import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.view.WindowManager.TRANSIT_OPEN; @@ -50,7 +49,7 @@ import com.android.wm.shell.transition.Transitions; public class PipTransition extends PipTransitionController { private static final String TAG = PipTransition.class.getSimpleName(); - private PipScheduler mPipScheduler; + private final PipScheduler mPipScheduler; @Nullable private WindowContainerToken mPipTaskToken; @Nullable @@ -168,14 +167,9 @@ public class PipTransition extends PipTransitionController { } mPipTaskToken = pipChange.getContainer(); - // cache the PiP task token and the relevant leashes + // cache the PiP task token and leash mPipScheduler.setPipTaskToken(mPipTaskToken); mPipScheduler.setPinnedTaskLeash(pipChange.getLeash()); - // check if we entered PiP from a multi-activity task and set the original task leash - final int lastParentTaskId = pipChange.getTaskInfo().lastParentTaskIdBeforePip; - final boolean isSingleActivity = lastParentTaskId == INVALID_TASK_ID; - mPipScheduler.setOriginalTaskLeash(isSingleActivity ? null : - findChangeByTaskId(info, lastParentTaskId).getLeash()); startTransaction.apply(); finishCallback.onTransitionFinished(null); @@ -201,17 +195,6 @@ public class PipTransition extends PipTransitionController { return null; } - @Nullable - private TransitionInfo.Change findChangeByTaskId(TransitionInfo info, int taskId) { - for (TransitionInfo.Change change : info.getChanges()) { - if (change.getTaskInfo() != null - && change.getTaskInfo().taskId == taskId) { - return change; - } - } - return null; - } - private void onExitPip() { mPipTaskToken = null; mPipScheduler.onExitPip(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java index c2f15f6cba75..e6418f35a0b1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java @@ -182,7 +182,7 @@ public class TaskSnapshotWindow { try { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_STARTING_WINDOW, "Removing taskSnapshot surface, mHasDrawn=%b", mHasDrawn); - mSession.remove(mWindow); + mSession.remove(mWindow.asBinder()); } catch (RemoteException e) { // nothing } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index 723a4a7ca664..193a4fb5b503 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -60,6 +60,7 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN; import static com.android.wm.shell.transition.TransitionAnimationHelper.edgeExtendWindow; import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet; +import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionTypeFromInfo; import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation; import android.animation.Animator; @@ -424,7 +425,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { // Don't animate anything that isn't independent. if (!TransitionInfo.isIndependent(change, info)) continue; - Animation a = loadAnimation(info, change, wallpaperTransit, isDreamTransition); + final int type = getTransitionTypeFromInfo(info); + Animation a = loadAnimation(type, info, change, wallpaperTransit, isDreamTransition); if (a != null) { if (isTask) { final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0; @@ -660,12 +662,11 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } @Nullable - private Animation loadAnimation(@NonNull TransitionInfo info, - @NonNull TransitionInfo.Change change, int wallpaperTransit, - boolean isDreamTransition) { + private Animation loadAnimation(@WindowManager.TransitionType int type, + @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, + int wallpaperTransit, boolean isDreamTransition) { Animation a; - final int type = info.getType(); final int flags = info.getFlags(); final int changeMode = change.getMode(); final int changeFlags = change.getFlags(); @@ -721,7 +722,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { return null; } else { a = loadAttributeAnimation( - info, change, wallpaperTransit, mTransitionAnimation, isDreamTransition); + type, info, change, wallpaperTransit, mTransitionAnimation, isDreamTransition); } if (a != null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java index d07d2b7b6db9..b012d359931a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.transitTypeToString; import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW; +import static android.window.TransitionInfo.FLAG_IS_DISPLAY; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; @@ -45,6 +46,7 @@ import android.graphics.Rect; import android.graphics.Shader; import android.view.Surface; import android.view.SurfaceControl; +import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.Transformation; import android.window.ScreenCapture; @@ -61,10 +63,10 @@ public class TransitionAnimationHelper { /** Loads the animation that is defined through attribute id for the given transition. */ @Nullable - public static Animation loadAttributeAnimation(@NonNull TransitionInfo info, + public static Animation loadAttributeAnimation(@WindowManager.TransitionType int type, + @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change, int wallpaperTransit, @NonNull TransitionAnimation transitionAnimation, boolean isDreamTransition) { - final int type = info.getType(); final int changeMode = change.getMode(); final int changeFlags = change.getFlags(); final boolean enter = TransitionUtil.isOpeningType(changeMode); @@ -186,6 +188,38 @@ public class TransitionAnimationHelper { return options.getCustomActivityTransition(isOpen); } + /** + * Gets the final transition type from {@link TransitionInfo} for determining the animation. + */ + public static int getTransitionTypeFromInfo(@NonNull TransitionInfo info) { + final int type = info.getType(); + // If the info transition type is opening transition, iterate its changes to see if it + // has any opening change, if none, returns TRANSIT_CLOSE type for closing animation. + if (type == TRANSIT_OPEN) { + boolean hasOpenTransit = false; + for (TransitionInfo.Change change : info.getChanges()) { + if ((change.getTaskInfo() != null || change.hasFlags(FLAG_IS_DISPLAY)) + && !TransitionUtil.isOrderOnly(change)) { + // This isn't an activity-level transition. + return type; + } + if (change.getTaskInfo() != null + && change.hasFlags(FLAG_IS_DISPLAY | FLAGS_IS_NON_APP_WINDOW)) { + // Ignore non-activity containers. + continue; + } + if (change.getMode() == TRANSIT_OPEN) { + hasOpenTransit = true; + break; + } + } + if (!hasOpenTransit) { + return TRANSIT_CLOSE; + } + } + return type; + } + static Animation loadCustomActivityTransition( @NonNull TransitionInfo.AnimationOptions.CustomActivityTransition transitionAnim, TransitionInfo.AnimationOptions options, boolean enter, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index aff35a347183..c12ac8b3772e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -149,7 +149,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mDecorationContainerSurface, mDragPositioningCallback, mSurfaceControlBuilderSupplier, - mSurfaceControlTransactionSupplier); + mSurfaceControlTransactionSupplier, + mDisplayController); } final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()) 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 eba1a36ef29f..e1d177af2331 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 @@ -293,7 +293,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mDecorationContainerSurface, mDragPositioningCallback, mSurfaceControlBuilderSupplier, - mSurfaceControlTransactionSupplier); + mSurfaceControlTransactionSupplier, + mDisplayController); } final int touchSlop = ViewConfiguration.get(mResult.mRootView.getContext()) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java index 1669cf4a222c..8ce2d6d6d092 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java @@ -40,8 +40,9 @@ public interface DragPositioningCallback { * {@code 0} to indicate it's a move * @param x x coordinate in window decoration coordinate system where the drag starts * @param y y coordinate in window decoration coordinate system where the drag starts + * @return the starting task bounds */ - void onDragPositioningStart(@CtrlType int ctrlType, float x, float y); + Rect onDragPositioningStart(@CtrlType int ctrlType, float x, float y); /** * Called when the pointer moves during a drag-resize or drag-move. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java index 518f4b87e197..8cbcde320795 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java @@ -50,6 +50,8 @@ import android.view.ViewConfiguration; import android.view.WindowManagerGlobal; import com.android.internal.view.BaseIWindow; +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayLayout; import java.util.function.Supplier; @@ -78,6 +80,7 @@ class DragResizeInputListener implements AutoCloseable { private final SurfaceControl mInputSinkSurface; private final BaseIWindow mFakeSinkWindow; private final InputChannel mSinkInputChannel; + private final DisplayController mDisplayController; private int mTaskWidth; private int mTaskHeight; @@ -92,6 +95,7 @@ class DragResizeInputListener implements AutoCloseable { private int mDragPointerId = -1; private DragDetector mDragDetector; + private final Region mTouchRegion = new Region(); DragResizeInputListener( Context context, @@ -102,7 +106,8 @@ class DragResizeInputListener implements AutoCloseable { SurfaceControl decorationSurface, DragPositioningCallback callback, Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, - Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { + Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, + DisplayController displayController) { mInputManager = context.getSystemService(InputManager.class); mHandler = handler; mChoreographer = choreographer; @@ -110,6 +115,7 @@ class DragResizeInputListener implements AutoCloseable { mDisplayId = displayId; mTaskCornerRadius = taskCornerRadius; mDecorationSurface = decorationSurface; + mDisplayController = displayController; // Use a fake window as the backing surface is a container layer, and we don't want to // create a buffer layer for it, so we can't use ViewRootImpl. mFakeWindow = new BaseIWindow(); @@ -195,34 +201,34 @@ class DragResizeInputListener implements AutoCloseable { mCornerSize = cornerSize; mDragDetector.setTouchSlop(touchSlop); - Region touchRegion = new Region(); + mTouchRegion.setEmpty(); final Rect topInputBounds = new Rect( -mResizeHandleThickness, -mResizeHandleThickness, mTaskWidth + mResizeHandleThickness, 0); - touchRegion.union(topInputBounds); + mTouchRegion.union(topInputBounds); final Rect leftInputBounds = new Rect( -mResizeHandleThickness, 0, 0, mTaskHeight); - touchRegion.union(leftInputBounds); + mTouchRegion.union(leftInputBounds); final Rect rightInputBounds = new Rect( mTaskWidth, 0, mTaskWidth + mResizeHandleThickness, mTaskHeight); - touchRegion.union(rightInputBounds); + mTouchRegion.union(rightInputBounds); final Rect bottomInputBounds = new Rect( -mResizeHandleThickness, mTaskHeight, mTaskWidth + mResizeHandleThickness, mTaskHeight + mResizeHandleThickness); - touchRegion.union(bottomInputBounds); + mTouchRegion.union(bottomInputBounds); // Set up touch areas in each corner. int cornerRadius = mCornerSize / 2; @@ -231,28 +237,28 @@ class DragResizeInputListener implements AutoCloseable { -cornerRadius, cornerRadius, cornerRadius); - touchRegion.union(mLeftTopCornerBounds); + mTouchRegion.union(mLeftTopCornerBounds); mRightTopCornerBounds = new Rect( mTaskWidth - cornerRadius, -cornerRadius, mTaskWidth + cornerRadius, cornerRadius); - touchRegion.union(mRightTopCornerBounds); + mTouchRegion.union(mRightTopCornerBounds); mLeftBottomCornerBounds = new Rect( -cornerRadius, mTaskHeight - cornerRadius, cornerRadius, mTaskHeight + cornerRadius); - touchRegion.union(mLeftBottomCornerBounds); + mTouchRegion.union(mLeftBottomCornerBounds); mRightBottomCornerBounds = new Rect( mTaskWidth - cornerRadius, mTaskHeight - cornerRadius, mTaskWidth + cornerRadius, mTaskHeight + cornerRadius); - touchRegion.union(mRightBottomCornerBounds); + mTouchRegion.union(mRightBottomCornerBounds); try { mWindowSession.updateInputChannel( @@ -262,7 +268,7 @@ class DragResizeInputListener implements AutoCloseable { FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY, - touchRegion); + mTouchRegion); } catch (RemoteException e) { e.rethrowFromSystemServer(); } @@ -281,19 +287,8 @@ class DragResizeInputListener implements AutoCloseable { // issue. However, were there touchscreen-only a region out of the task bounds, mouse // gestures will become no-op in that region, even though the mouse gestures may appear to // be performed on the input window behind the resize handle. - touchRegion.op(0, 0, mTaskWidth, mTaskHeight, Region.Op.DIFFERENCE); - try { - mWindowSession.updateInputChannel( - mSinkInputChannel.getToken(), - mDisplayId, - mInputSinkSurface, - FLAG_NOT_FOCUSABLE, - 0 /* privateFlags */, - INPUT_FEATURE_NO_INPUT_CHANNEL, - touchRegion); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } + mTouchRegion.op(0, 0, mTaskWidth, mTaskHeight, Region.Op.DIFFERENCE); + updateSinkInputChannel(mTouchRegion); return true; } @@ -309,19 +304,34 @@ class DragResizeInputListener implements AutoCloseable { return region; } + private void updateSinkInputChannel(Region region) { + try { + mWindowSession.updateInputChannel( + mSinkInputChannel.getToken(), + mDisplayId, + mInputSinkSurface, + FLAG_NOT_FOCUSABLE, + 0 /* privateFlags */, + INPUT_FEATURE_NO_INPUT_CHANNEL, + region); + } catch (RemoteException ex) { + ex.rethrowFromSystemServer(); + } + } + @Override public void close() { mInputEventReceiver.dispose(); mInputChannel.dispose(); try { - mWindowSession.remove(mFakeWindow); + mWindowSession.remove(mFakeWindow.asBinder()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } mSinkInputChannel.dispose(); try { - mWindowSession.remove(mFakeSinkWindow); + mWindowSession.remove(mFakeSinkWindow.asBinder()); } catch (RemoteException e) { e.rethrowFromSystemServer(); } @@ -337,6 +347,7 @@ class DragResizeInputListener implements AutoCloseable { private boolean mConsumeBatchEventScheduled; private boolean mShouldHandleEvents; private int mLastCursorType = PointerIcon.TYPE_DEFAULT; + private Rect mDragStartTaskBounds; private TaskResizeInputEventReceiver( InputChannel inputChannel, Handler handler, Choreographer choreographer) { @@ -398,12 +409,15 @@ class DragResizeInputListener implements AutoCloseable { } if (mShouldHandleEvents) { mInputManager.pilferPointers(mInputChannel.getToken()); - mDragPointerId = e.getPointerId(0); float rawX = e.getRawX(0); float rawY = e.getRawY(0); int ctrlType = calculateCtrlType(isTouch, x, y); - mCallback.onDragPositioningStart(ctrlType, rawX, rawY); + mDragStartTaskBounds = mCallback.onDragPositioningStart(ctrlType, + rawX, rawY); + // Increase the input sink region to cover the whole screen; this is to + // prevent input and focus from going to other tasks during a drag resize. + updateInputSinkRegionForDrag(mDragStartTaskBounds); result = true; } break; @@ -415,7 +429,8 @@ class DragResizeInputListener implements AutoCloseable { int dragPointerIndex = e.findPointerIndex(mDragPointerId); float rawX = e.getRawX(dragPointerIndex); float rawY = e.getRawY(dragPointerIndex); - mCallback.onDragPositioningMove(rawX, rawY); + final Rect taskBounds = mCallback.onDragPositioningMove(rawX, rawY); + updateInputSinkRegionForDrag(taskBounds); result = true; break; } @@ -423,8 +438,13 @@ class DragResizeInputListener implements AutoCloseable { case MotionEvent.ACTION_CANCEL: { if (mShouldHandleEvents) { int dragPointerIndex = e.findPointerIndex(mDragPointerId); - mCallback.onDragPositioningEnd( + final Rect taskBounds = mCallback.onDragPositioningEnd( e.getRawX(dragPointerIndex), e.getRawY(dragPointerIndex)); + // If taskBounds has changed, setGeometry will be called and update the + // sink region. Otherwise, we should revert it here. + if (taskBounds.equals(mDragStartTaskBounds)) { + updateSinkInputChannel(mTouchRegion); + } } mShouldHandleEvents = false; mDragPointerId = -1; @@ -444,6 +464,18 @@ class DragResizeInputListener implements AutoCloseable { return result; } + private void updateInputSinkRegionForDrag(Rect taskBounds) { + final DisplayLayout layout = mDisplayController.getDisplayLayout(mDisplayId); + final Region dragTouchRegion = new Region(-taskBounds.left, + -taskBounds.top, + -taskBounds.left + layout.width(), + -taskBounds.top + layout.height()); + // Remove the localized task bounds from the touch region. + taskBounds.offsetTo(0, 0); + dragTouchRegion.op(taskBounds, Region.Op.DIFFERENCE); + updateSinkInputChannel(dragTouchRegion); + } + private boolean isInCornerBounds(float xf, float yf) { return calculateCornersCtrlType(xf, yf) != 0; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java index dadd264596fb..bf11c8bc4f79 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java @@ -68,7 +68,7 @@ class FluidResizeTaskPositioner implements DragPositioningCallback { } @Override - public void onDragPositioningStart(int ctrlType, float x, float y) { + public Rect onDragPositioningStart(int ctrlType, float x, float y) { mCtrlType = ctrlType; mTaskBoundsAtDragStart.set( mWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds()); @@ -87,6 +87,7 @@ class FluidResizeTaskPositioner implements DragPositioningCallback { mDisplayController.getDisplayLayout(mWindowDecoration.mDisplay.getDisplayId()) .getStableBounds(mStableBounds); } + return mRepositionTaskBounds; } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java index 852c037baad5..79fec0978a12 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java @@ -85,7 +85,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, } @Override - public void onDragPositioningStart(int ctrlType, float x, float y) { + public Rect onDragPositioningStart(int ctrlType, float x, float y) { mCtrlType = ctrlType; mTaskBoundsAtDragStart.set( mDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds()); @@ -107,6 +107,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback, mDisplayController.getDisplayLayout(mDesktopWindowDecoration.mDisplay.getDisplayId()) .getStableBounds(mStableBounds); } + return mRepositionTaskBounds; } @Override diff --git a/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto index 406ada97a07d..5a017ad21044 100644 --- a/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/flicker/appcompat/trace_config/trace_config.textproto @@ -63,11 +63,7 @@ data_sources: { atrace_categories: "sched_process_exit" atrace_apps: "com.android.server.wm.flicker.testapp" atrace_apps: "com.android.systemui" - atrace_apps: "com.android.wm.shell.flicker" atrace_apps: "com.android.wm.shell.flicker.other" - atrace_apps: "com.android.wm.shell.flicker.bubbles" - atrace_apps: "com.android.wm.shell.flicker.pip" - atrace_apps: "com.android.wm.shell.flicker.splitscreen" atrace_apps: "com.google.android.apps.nexuslauncher" } } diff --git a/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto index 406ada97a07d..15998311e43a 100644 --- a/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/flicker/bubble/trace_config/trace_config.textproto @@ -63,11 +63,7 @@ data_sources: { atrace_categories: "sched_process_exit" atrace_apps: "com.android.server.wm.flicker.testapp" atrace_apps: "com.android.systemui" - atrace_apps: "com.android.wm.shell.flicker" - atrace_apps: "com.android.wm.shell.flicker.other" atrace_apps: "com.android.wm.shell.flicker.bubbles" - atrace_apps: "com.android.wm.shell.flicker.pip" - atrace_apps: "com.android.wm.shell.flicker.splitscreen" atrace_apps: "com.google.android.apps.nexuslauncher" } } diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt index 42191d1c5feb..182a9089d040 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/AppsEnterPipTransition.kt @@ -31,10 +31,18 @@ import org.junit.runners.Parameterized abstract class AppsEnterPipTransition(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) { protected abstract val standardAppHelper: StandardAppHelper + protected abstract val permissions: Array<String> + @FlickerBuilderProvider override fun buildFlicker(): FlickerBuilder { return FlickerBuilder(instrumentation).apply { instrumentation.uiAutomation.adoptShellPermissionIdentity() + for (permission in permissions) { + instrumentation.uiAutomation.grantRuntimePermission( + standardAppHelper.packageName, + permission + ) + } setup { flicker.scenario.setIsTablet(tapl.isTablet) } transition() } diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt index 4da52ef1272c..d06cf775ca60 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/MapsEnterPipTest.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.flicker.pip.apps +import android.Manifest import android.content.Context import android.location.Criteria import android.location.Location @@ -64,6 +65,9 @@ import org.junit.runners.Parameterized open class MapsEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) { override val standardAppHelper: MapsAppHelper = MapsAppHelper(instrumentation) + override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS, + Manifest.permission.ACCESS_FINE_LOCATION) + val locationManager: LocationManager = instrumentation.context.getSystemService(Context.LOCATION_SERVICE) as LocationManager val mainHandler = Handler(Looper.getMainLooper()) diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt index 5498e8c4f970..32f12592135d 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.flicker.pip.apps +import android.Manifest import android.platform.test.annotations.Postsubmit import android.tools.common.NavBar import android.tools.common.Rotation @@ -62,6 +63,8 @@ import org.junit.runners.Parameterized open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) { override val standardAppHelper: NetflixAppHelper = NetflixAppHelper(instrumentation) + override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS) + override val defaultEnterPip: FlickerBuilder.() -> Unit = { setup { standardAppHelper.launchViaIntent( diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt index d8afc25caf71..509b32c11afe 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.flicker.pip.apps +import android.Manifest import android.platform.test.annotations.Postsubmit import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.apphelpers.YouTubeAppHelper @@ -58,6 +59,8 @@ import org.junit.runners.Parameterized open class YouTubeEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) { override val standardAppHelper: YouTubeAppHelper = YouTubeAppHelper(instrumentation) + override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS) + override val defaultEnterPip: FlickerBuilder.() -> Unit = { setup { standardAppHelper.launchViaIntent( diff --git a/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto index 406ada97a07d..fc15ff9b9af8 100644 --- a/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/flicker/pip/trace_config/trace_config.textproto @@ -63,11 +63,7 @@ data_sources: { atrace_categories: "sched_process_exit" atrace_apps: "com.android.server.wm.flicker.testapp" atrace_apps: "com.android.systemui" - atrace_apps: "com.android.wm.shell.flicker" - atrace_apps: "com.android.wm.shell.flicker.other" - atrace_apps: "com.android.wm.shell.flicker.bubbles" atrace_apps: "com.android.wm.shell.flicker.pip" - atrace_apps: "com.android.wm.shell.flicker.splitscreen" atrace_apps: "com.google.android.apps.nexuslauncher" } } diff --git a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto index 406ada97a07d..9f2e49755fec 100644 --- a/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/flicker/service/trace_config/trace_config.textproto @@ -63,11 +63,7 @@ data_sources: { atrace_categories: "sched_process_exit" atrace_apps: "com.android.server.wm.flicker.testapp" atrace_apps: "com.android.systemui" - atrace_apps: "com.android.wm.shell.flicker" - atrace_apps: "com.android.wm.shell.flicker.other" - atrace_apps: "com.android.wm.shell.flicker.bubbles" - atrace_apps: "com.android.wm.shell.flicker.pip" - atrace_apps: "com.android.wm.shell.flicker.splitscreen" + atrace_apps: "com.android.wm.shell.flicker.service" atrace_apps: "com.google.android.apps.nexuslauncher" } } diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto b/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto index 406ada97a07d..b55f4ecdb6a4 100644 --- a/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto +++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/trace_config/trace_config.textproto @@ -63,10 +63,6 @@ data_sources: { atrace_categories: "sched_process_exit" atrace_apps: "com.android.server.wm.flicker.testapp" atrace_apps: "com.android.systemui" - atrace_apps: "com.android.wm.shell.flicker" - atrace_apps: "com.android.wm.shell.flicker.other" - atrace_apps: "com.android.wm.shell.flicker.bubbles" - atrace_apps: "com.android.wm.shell.flicker.pip" atrace_apps: "com.android.wm.shell.flicker.splitscreen" atrace_apps: "com.google.android.apps.nexuslauncher" } 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 4e300d9a7e69..01c9bd0cb9f7 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 @@ -40,6 +40,8 @@ import static android.window.TransitionInfo.FLAG_SYNC; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionTypeFromInfo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -93,6 +95,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; +import com.android.internal.R; +import com.android.internal.policy.TransitionAnimation; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestShellExecutor; @@ -1463,6 +1467,43 @@ public class ShellTransitionTests extends ShellTestCase { assertEquals(0, mDefaultHandler.activeCount()); } + @Test + public void testCloseTransitAnimationWhenClosingChangesExists() { + Transitions transitions = createTestTransitions(); + Transitions.TransitionObserver observer = mock(Transitions.TransitionObserver.class); + transitions.registerObserver(observer); + transitions.replaceDefaultHandlerForTest(mDefaultHandler); + final TransitionAnimation transitionAnimation = new TransitionAnimation(mContext, false, + Transitions.TAG); + spyOn(transitionAnimation); + + // Creating a transition by the app hooking the back key event to start the + // previous activity with FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + // flags in order to clear the top activity and bring the exist previous activity to front. + // Expects the activity transition should playing the close animation instead the initiated + // open animation made by startActivity. + IBinder transitToken = new Binder(); + transitions.requestStartTransition(transitToken, + new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); + TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN) + .addChange(TRANSIT_CLOSE).addChange(TRANSIT_TO_FRONT).build(); + transitions.onTransitionReady(transitToken, info, new StubTransaction(), + new StubTransaction()); + + final int type = getTransitionTypeFromInfo(info); + assertEquals(TRANSIT_CLOSE, type); + + TransitionAnimationHelper.loadAttributeAnimation(type, info, info.getChanges().get(0), 0, + transitionAnimation, false); + verify(transitionAnimation).loadDefaultAnimationAttr( + eq(R.styleable.WindowAnimation_activityCloseExitAnimation), anyBoolean()); + + TransitionAnimationHelper.loadAttributeAnimation(type, info, info.getChanges().get(1), 0, + transitionAnimation, false); + verify(transitionAnimation).loadDefaultAnimationAttr( + eq(R.styleable.WindowAnimation_activityCloseEnterAnimation), anyBoolean()); + } + class ChangeBuilder { final TransitionInfo.Change mChange; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 31fc929dfcdf..008ea3aaa2e7 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -589,10 +589,40 @@ void SkiaCanvas::drawMesh(const Mesh& mesh, sk_sp<SkBlender> blender, const Pain // Canvas draw operations: Bitmaps // ---------------------------------------------------------------------------- +bool SkiaCanvas::useGainmapShader(Bitmap& bitmap) { + // If the bitmap doesn't have a gainmap, don't use the gainmap shader + if (!bitmap.hasGainmap()) return false; + + // If we don't have an owned canvas, then we're either hardware accelerated or drawing + // to a picture - use the gainmap shader out of caution. Ideally a picture canvas would + // use a drawable here instead to defer making that decision until the last possible + // moment + if (!mCanvasOwned) return true; + + auto info = mCanvasOwned->imageInfo(); + + // If it's an unknown colortype then it's not a bitmap-backed canvas + if (info.colorType() == SkColorType::kUnknown_SkColorType) return true; + + skcms_TransferFunction tfn; + info.colorSpace()->transferFn(&tfn); + + auto transferType = skcms_TransferFunction_getType(&tfn); + switch (transferType) { + case skcms_TFType_HLGish: + case skcms_TFType_HLGinvish: + case skcms_TFType_PQish: + return true; + case skcms_TFType_Invalid: + case skcms_TFType_sRGBish: + return false; + } +} + void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) { auto image = bitmap.makeImage(); - if (bitmap.hasGainmap()) { + if (useGainmapShader(bitmap)) { Paint gainmapPaint = paint ? *paint : Paint(); sk_sp<SkShader> gainmapShader = uirenderer::MakeGainmapShader( image, bitmap.gainmap()->bitmap->makeImage(), bitmap.gainmap()->info, @@ -619,7 +649,7 @@ void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float s SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom); SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); - if (bitmap.hasGainmap()) { + if (useGainmapShader(bitmap)) { Paint gainmapPaint = paint ? *paint : Paint(); sk_sp<SkShader> gainmapShader = uirenderer::MakeGainmapShader( image, bitmap.gainmap()->bitmap->makeImage(), bitmap.gainmap()->info, diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index ced02241ffe2..4bf1790e2415 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -223,6 +223,8 @@ private: void drawPoints(const float* points, int count, const Paint& paint, SkCanvas::PointMode mode); + bool useGainmapShader(Bitmap& bitmap); + class Clip; std::unique_ptr<SkCanvas> mCanvasOwned; // Might own a canvas we allocated. diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h index caffdfc907f7..ef4dce57bf46 100644 --- a/libs/hwui/hwui/Paint.h +++ b/libs/hwui/hwui/Paint.h @@ -17,19 +17,19 @@ #ifndef ANDROID_GRAPHICS_PAINT_H_ #define ANDROID_GRAPHICS_PAINT_H_ -#include "Typeface.h" - -#include <cutils/compiler.h> - #include <SkFont.h> #include <SkPaint.h> #include <SkSamplingOptions.h> -#include <string> - -#include <minikin/FontFamily.h> +#include <cutils/compiler.h> #include <minikin/FamilyVariant.h> +#include <minikin/FontFamily.h> +#include <minikin/FontFeature.h> #include <minikin/Hyphenator.h> +#include <string> + +#include "Typeface.h" + namespace android { class BlurDrawLooper; @@ -82,11 +82,15 @@ public: float getWordSpacing() const { return mWordSpacing; } - void setFontFeatureSettings(const std::string& fontFeatureSettings) { - mFontFeatureSettings = fontFeatureSettings; + void setFontFeatureSettings(std::string_view fontFeatures) { + mFontFeatureSettings = minikin::FontFeature::parse(fontFeatures); } - std::string getFontFeatureSettings() const { return mFontFeatureSettings; } + void resetFontFeatures() { mFontFeatureSettings.clear(); } + + const std::vector<minikin::FontFeature>& getFontFeatureSettings() const { + return mFontFeatureSettings; + } void setMinikinLocaleListId(uint32_t minikinLocaleListId) { mMinikinLocaleListId = minikinLocaleListId; @@ -170,7 +174,7 @@ private: float mLetterSpacing = 0; float mWordSpacing = 0; - std::string mFontFeatureSettings; + std::vector<minikin::FontFeature> mFontFeatureSettings; uint32_t mMinikinLocaleListId; std::optional<minikin::FamilyVariant> mFamilyVariant; uint32_t mHyphenEdit = 0; diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index 8c71d6fc7860..d84b73d1a1ca 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -33,6 +33,7 @@ #include <cassert> #include <cstring> #include <memory> +#include <string_view> #include <vector> #include "ColorFilter.h" @@ -690,10 +691,11 @@ namespace PaintGlue { jstring settings) { Paint* paint = reinterpret_cast<Paint*>(paintHandle); if (!settings) { - paint->setFontFeatureSettings(std::string()); + paint->resetFontFeatures(); } else { ScopedUtfChars settingsChars(env, settings); - paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); + paint->setFontFeatureSettings( + std::string_view(settingsChars.c_str(), settingsChars.size())); } } diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt index 98ad22c8060e..42f1207c69cb 100644 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/IntentParser.kt @@ -19,35 +19,46 @@ package com.android.credentialmanager import android.content.Intent import android.content.pm.PackageManager import android.credentials.ui.RequestInfo +import android.util.Log +import com.android.credentialmanager.ktx.appLabel +import com.android.credentialmanager.ktx.cancelUiRequest import com.android.credentialmanager.ktx.requestInfo import com.android.credentialmanager.mapper.toGet -import com.android.credentialmanager.mapper.toRequestCancel -import com.android.credentialmanager.mapper.toRequestClose import com.android.credentialmanager.model.Request fun Intent.parse( packageManager: PackageManager, - previousIntent: Intent? = null, ): Request { - this.toRequestClose(previousIntent)?.let { closeRequest -> - return closeRequest - } - - this.toRequestCancel(packageManager)?.let { cancelRequest -> - return cancelRequest - } + return parseCancelUiRequest(packageManager) + ?: parseRequestInfo() +} - return when (requestInfo?.type) { - RequestInfo.TYPE_CREATE -> { - Request.Create +fun Intent.parseCancelUiRequest(packageManager: PackageManager): Request? = + this.cancelUiRequest?.let { cancelUiRequest -> + val showCancel = cancelUiRequest.shouldShowCancellationUi().apply { + Log.d(TAG, "Received UI cancel request, shouldShowCancellationUi: $this") } - - RequestInfo.TYPE_GET -> { - this.toGet() + if (showCancel) { + val appLabel = packageManager.appLabel(cancelUiRequest.appPackageName) + if (appLabel == null) { + Log.d(TAG, "Received UI cancel request with an invalid package name.") + null + } else { + Request.Cancel(appName = appLabel, token = cancelUiRequest.token) + } + } else { + Request.Close(cancelUiRequest.token) } + } - else -> { - throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}") +fun Intent.parseRequestInfo(): Request = + requestInfo.let{ info -> + when (info?.type) { + RequestInfo.TYPE_CREATE -> Request.Create(info.token) + RequestInfo.TYPE_GET -> toGet() + else -> { + throw IllegalStateException("Unrecognized request type: ${info?.type}") + } } } -} + diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/CredentialManagerClient.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/CredentialManagerClient.kt new file mode 100644 index 000000000000..49387cf410ac --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/CredentialManagerClient.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.credentialmanager.client + +import android.content.Intent +import android.credentials.ui.BaseDialogResult +import android.credentials.ui.UserSelectionDialogResult +import com.android.credentialmanager.model.Request +import kotlinx.coroutines.flow.StateFlow + +interface CredentialManagerClient { + /** The UI should monitor the request update. */ + val requests: StateFlow<Request?> + + /** The UI got a new intent; update the request state. */ + fun updateRequest(intent: Intent) + + /** Sends an error encountered during the UI. */ + fun sendError( + @BaseDialogResult.ResultCode resultCode: Int, + errorMessage: String? = null, + ) + + /** + * Sends a response to the system service. The response + * contains information about the user's choice from the selector + * UI and the result of the provider operation launched with + * that selection. + * + * If the user choice was a normal entry, then the UI can finish + * the activity immediately. Otherwise if it was an authentication + * (locked) entry, then the UI will need to stay up and wait for + * a new intent from the system containing the new data for + * display. + * + * Note that if the provider operation returns RESULT_CANCELED, + * then the selector should not send that result back, and instead + * re-display the options to allow a user to have another choice. + * + * @throws [IllegalStateException] if [requests] is not [Request.Get]. + */ + fun sendResult(result: UserSelectionDialogResult) +}
\ No newline at end of file diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt new file mode 100644 index 000000000000..83183b5f58eb --- /dev/null +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/client/impl/CredentialManagerClientImpl.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.credentialmanager.client.impl + +import android.content.Intent +import android.content.pm.PackageManager +import android.credentials.ui.BaseDialogResult +import android.credentials.ui.UserSelectionDialogResult +import android.os.Bundle +import android.util.Log +import com.android.credentialmanager.TAG +import com.android.credentialmanager.model.Request +import com.android.credentialmanager.parse +import com.android.credentialmanager.client.CredentialManagerClient +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +class CredentialManagerClientImpl @Inject constructor( + private val packageManager: PackageManager, +) : CredentialManagerClient { + + private val _requests = MutableStateFlow<Request?>(null) + override val requests: StateFlow<Request?> = _requests + + + override fun updateRequest(intent: Intent) { + val request = intent.parse( + packageManager = packageManager, + ) + Log.d(TAG, "Request parsed: $request, client instance: $this") + if (request is Request.Cancel || request is Request.Close) { + if (request.token != null && request.token != _requests.value?.token) { + Log.w(TAG, "drop terminate request for previous session.") + return + } + } + _requests.value = request + } + + override fun sendError(resultCode: Int, errorMessage: String?) { + TODO("b/300422310 - [Wear] Implement UI for cancellation request with message") + } + + override fun sendResult(result: UserSelectionDialogResult) { + val currentRequest = requests.value + check(currentRequest is Request.Get) { "current request is not get." } + currentRequest.resultReceiver?.let { receiver -> + val resultDataBundle = Bundle() + UserSelectionDialogResult.addToBundle(result, resultDataBundle) + receiver.send( + BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION, + resultDataBundle + ) + } + } +} diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt deleted file mode 100644 index 99dc9ec38eff..000000000000 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCancelMapper.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0N - * - * 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.credentialmanager.mapper - -import android.content.Intent -import android.content.pm.PackageManager -import android.util.Log -import com.android.credentialmanager.TAG -import com.android.credentialmanager.ktx.appLabel -import com.android.credentialmanager.ktx.cancelUiRequest -import com.android.credentialmanager.model.Request - -fun Intent.toRequestCancel(packageManager: PackageManager): Request.Cancel? = - this.cancelUiRequest?.let { cancelUiRequest -> - val appLabel = packageManager.appLabel(cancelUiRequest.appPackageName) - if (appLabel == null) { - Log.d(TAG, "Received UI cancel request with an invalid package name.") - null - } else { - Request.Cancel(appName = appLabel) - } - } diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCloseMapper.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCloseMapper.kt deleted file mode 100644 index 02ee77bc5ec3..000000000000 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/mapper/RequestCloseMapper.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0N - * - * 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.credentialmanager.mapper - -import android.content.Intent -import com.android.credentialmanager.ktx.cancelUiRequest -import com.android.credentialmanager.ktx.requestInfo -import com.android.credentialmanager.model.Request - -fun Intent.toRequestClose( - previousIntent: Intent? = null, -): Request.Close? { - // Close request comes as "Cancel" request from Credential Manager API - this.cancelUiRequest?.let { cancelUiRequest -> - - if (cancelUiRequest.shouldShowCancellationUi()) { - // Current request is to Cancel and not to Close - return null - } - - previousIntent?.let { - val previousToken = previousIntent.requestInfo?.token - val currentToken = this.requestInfo?.token - - if (previousToken != currentToken) { - // Current cancellation is for a different request, don't close the current flow. - return null - } - } - - return Request.Close - } - - return null -}
\ No newline at end of file diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt index ed98f3ed5154..2289ed7320ca 100644 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt +++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/model/Request.kt @@ -25,33 +25,40 @@ import com.google.common.collect.ImmutableMap /** * Represents the request made by the CredentialManager API. */ -sealed class Request { +sealed class Request private constructor( + open val token: IBinder?, +) { /** * Request to close the app without displaying a message to the user and without reporting * anything back to the Credential Manager service. */ - data object Close : Request() + data class Close( + override val token: IBinder?, + ) : Request(token) /** * Request to close the app, displaying a message to the user. */ data class Cancel( - val appName: String - ) : Request() + val appName: String, + override val token: IBinder?, + ) : Request(token) /** * Request to start the get credentials flow. */ data class Get( - val token: IBinder?, + override val token: IBinder?, val resultReceiver: ResultReceiver?, val providers: ImmutableMap<String, ProviderData>, val passwordEntries: ImmutableList<Password>, - ) : Request() - + ) : Request(token) /** * Request to start the create credentials flow. */ - data object Create : Request() + data class Create( + override val token: IBinder?, + ) : Request(token) } + diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/PasswordRepository.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/PasswordRepository.kt deleted file mode 100644 index 5738feea0772..000000000000 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/PasswordRepository.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0N - * - * 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.credentialmanager.repository - -import android.content.Intent -import android.credentials.ui.BaseDialogResult -import android.credentials.ui.ProviderPendingIntentResponse -import android.credentials.ui.UserSelectionDialogResult -import android.os.Bundle -import android.util.Log -import com.android.credentialmanager.TAG -import com.android.credentialmanager.model.Password -import com.android.credentialmanager.model.Request -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class PasswordRepository @Inject constructor() { - - suspend fun selectPassword( - password: Password, - request: Request.Get, - resultCode: Int? = null, - resultData: Intent? = null, - ) { - Log.d(TAG, "password selected: {provider=${password.providerId}" + - ", key=${password.entry.key}, subkey=${password.entry.subkey}}") - - val userSelectionDialogResult = UserSelectionDialogResult( - request.token, - password.providerId, - password.entry.key, - password.entry.subkey, - if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null - ) - val resultDataBundle = Bundle() - UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultDataBundle) - request.resultReceiver?.send( - BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION, - resultDataBundle - ) - } -} diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/RequestRepository.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/RequestRepository.kt deleted file mode 100644 index 1973fc175c1f..000000000000 --- a/packages/CredentialManager/shared/src/com/android/credentialmanager/repository/RequestRepository.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0N - * - * 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.credentialmanager.repository - -import android.content.Intent -import android.content.pm.PackageManager -import android.util.Log -import com.android.credentialmanager.TAG -import com.android.credentialmanager.model.Request -import com.android.credentialmanager.parse -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class RequestRepository @Inject constructor( - private val packageManager: PackageManager, -) { - - private val _requests = MutableStateFlow<Request?>(null) - val requests: StateFlow<Request?> = _requests - - suspend fun processRequest(intent: Intent, previousIntent: Intent? = null) { - val request = intent.parse( - packageManager = packageManager, - previousIntent = previousIntent - ) - - Log.d(TAG, "Request parsed: $request") - - _requests.value = request - } -} diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt index f2df64aee22e..0df40d7adba5 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt @@ -25,6 +25,7 @@ import androidx.wear.compose.material.MaterialTheme import com.android.credentialmanager.ui.WearApp import com.google.android.horologist.annotations.ExperimentalHorologistApi import dagger.hilt.android.AndroidEntryPoint +import kotlin.system.exitProcess @AndroidEntryPoint(ComponentActivity::class) class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() { @@ -34,25 +35,21 @@ class CredentialSelectorActivity : Hilt_CredentialSelectorActivity() { @OptIn(ExperimentalHorologistApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setTheme(android.R.style.Theme_DeviceDefault) setContent { MaterialTheme { WearApp( viewModel = viewModel, - onCloseApp = ::finish, + onCloseApp = { exitProcess(0) }, ) } } - viewModel.onNewIntent(intent) + viewModel.updateRequest(intent) } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) - - val previousIntent = getIntent() setIntent(intent) - - viewModel.onNewIntent(intent, previousIntent) + viewModel.updateRequest(intent) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt index 435cd377114d..2a7e9e16a10e 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorViewModel.kt @@ -20,28 +20,27 @@ import android.content.Intent import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.android.credentialmanager.model.Request -import com.android.credentialmanager.repository.RequestRepository +import com.android.credentialmanager.client.CredentialManagerClient import com.android.credentialmanager.ui.mappers.toGet import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class CredentialSelectorViewModel @Inject constructor( - private val requestRepository: RequestRepository, + private val credentialManagerClient: CredentialManagerClient, ) : ViewModel() { - val uiState: StateFlow<CredentialSelectorUiState> = requestRepository.requests + val uiState: StateFlow<CredentialSelectorUiState> = credentialManagerClient.requests .map { request -> when (request) { null -> CredentialSelectorUiState.Idle is Request.Cancel -> CredentialSelectorUiState.Cancel(request.appName) - Request.Close -> CredentialSelectorUiState.Close - Request.Create -> CredentialSelectorUiState.Create + is Request.Close -> CredentialSelectorUiState.Close + is Request.Create -> CredentialSelectorUiState.Create is Request.Get -> request.toGet() } } @@ -51,10 +50,8 @@ class CredentialSelectorViewModel @Inject constructor( initialValue = CredentialSelectorUiState.Idle, ) - fun onNewIntent(intent: Intent, previousIntent: Intent? = null) { - viewModelScope.launch { - requestRepository.processRequest(intent = intent, previousIntent = previousIntent) - } + fun updateRequest(intent: Intent) { + credentialManagerClient.updateRequest(intent = intent) } } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt index cb1a4a13690e..6ededf3411bf 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/di/AppModule.kt @@ -2,17 +2,28 @@ package com.android.credentialmanager.di import android.content.Context import android.content.pm.PackageManager +import com.android.credentialmanager.client.CredentialManagerClient +import com.android.credentialmanager.client.impl.CredentialManagerClientImpl import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + @Module @InstallIn(SingletonComponent::class) internal object AppModule { @Provides + @Singleton @JvmStatic fun providePackageManager(@ApplicationContext context: Context): PackageManager = - context.packageManager + context.packageManager + + @Provides + @Singleton + @JvmStatic + fun provideCredentialManagerClient(packageManager: PackageManager): CredentialManagerClient = + CredentialManagerClientImpl(packageManager) } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Navigation.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Navigation.kt index da5697dab8d4..77fb3e7dfd9c 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Navigation.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/Navigation.kt @@ -19,9 +19,14 @@ package com.android.credentialmanager.ui import androidx.navigation.NavController fun NavController.navigateToLoading() { - navigate(Screen.Loading.route) + navigateToAsRoot(Screen.Loading.route) } fun NavController.navigateToSinglePasswordScreen() { - navigate(Screen.SinglePasswordScreen.route) + navigateToAsRoot(Screen.SinglePasswordScreen.route) +} + +fun NavController.navigateToAsRoot(route: String) { + popBackStack() + navigate(route) } diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt index 43514a039661..fb72c544c978 100644 --- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt +++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/single/password/SinglePasswordScreenViewModel.kt @@ -17,6 +17,8 @@ package com.android.credentialmanager.ui.screens.single.password import android.content.Intent +import android.credentials.ui.ProviderPendingIntentResponse +import android.credentials.ui.UserSelectionDialogResult import android.util.Log import androidx.activity.result.IntentSenderRequest import androidx.annotation.MainThread @@ -26,20 +28,17 @@ import com.android.credentialmanager.TAG import com.android.credentialmanager.ktx.getIntentSenderRequest import com.android.credentialmanager.model.Password import com.android.credentialmanager.model.Request -import com.android.credentialmanager.repository.PasswordRepository -import com.android.credentialmanager.repository.RequestRepository +import com.android.credentialmanager.client.CredentialManagerClient import com.android.credentialmanager.ui.model.PasswordUiModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class SinglePasswordScreenViewModel @Inject constructor( - private val requestRepository: RequestRepository, - private val passwordRepository: PasswordRepository, + private val credentialManagerClient: CredentialManagerClient, ) : ViewModel() { private var initializeCalled = false @@ -57,8 +56,8 @@ class SinglePasswordScreenViewModel @Inject constructor( initializeCalled = true viewModelScope.launch { - val request = requestRepository.requests.first() - Log.d(TAG, "request: $request") + val request = credentialManagerClient.requests.value + Log.d(TAG, "request: $request, client instance: $credentialManagerClient") if (request !is Request.Get) { _uiState.value = SinglePasswordScreenUiState.Error @@ -93,16 +92,15 @@ class SinglePasswordScreenViewModel @Inject constructor( resultCode: Int? = null, resultData: Intent? = null, ) { - viewModelScope.launch { - passwordRepository.selectPassword( - password = password, - request = requestGet, - resultCode = resultCode, - resultData = resultData - ) - - _uiState.value = SinglePasswordScreenUiState.Completed - } + val userSelectionDialogResult = UserSelectionDialogResult( + requestGet.token, + password.providerId, + password.entry.key, + password.entry.subkey, + if (resultCode != null) ProviderPendingIntentResponse(resultCode, resultData) else null + ) + credentialManagerClient.sendResult(userSelectionDialogResult) + _uiState.value = SinglePasswordScreenUiState.Completed } } diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml index 35f57723be7a..b845c2b6cc8b 100644 --- a/packages/PackageInstaller/AndroidManifest.xml +++ b/packages/PackageInstaller/AndroidManifest.xml @@ -86,6 +86,7 @@ android:exported="false" /> <activity android:name=".PackageInstallerActivity" + android:theme="@style/Theme.AlertDialogActivity.NoAnimation" android:exported="false" /> <activity android:name=".InstallInstalling" diff --git a/packages/PackageInstaller/res/values/themes.xml b/packages/PackageInstaller/res/values/themes.xml index aa1fa164b021..811fa7380c48 100644 --- a/packages/PackageInstaller/res/values/themes.xml +++ b/packages/PackageInstaller/res/values/themes.xml @@ -32,8 +32,8 @@ <item name="android:windowNoTitle">true</item> </style> - <style name="Theme.AlertDialogActivity.NoDim"> - <item name="android:windowNoTitle">true</item> + <style name="Theme.AlertDialogActivity.NoDim" + parent="@style/Theme.AlertDialogActivity.NoActionBar"> <item name="android:backgroundDimAmount">0</item> </style> diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java index 74f04e093162..eef21991b845 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java @@ -36,12 +36,14 @@ import androidx.annotation.Nullable; /** * Installation failed: Return status code to the caller or display failure UI to user */ -public class InstallFailed extends AlertActivity { +public class InstallFailed extends Activity { private static final String LOG_TAG = InstallFailed.class.getSimpleName(); /** Label of the app that failed to install */ private CharSequence mLabel; + private AlertDialog mDialog; + /** * Unhide the appropriate label for the statusCode. * @@ -53,19 +55,19 @@ public class InstallFailed extends AlertActivity { View viewToEnable; switch (statusCode) { case PackageInstaller.STATUS_FAILURE_BLOCKED: - viewToEnable = requireViewById(R.id.install_failed_blocked); + viewToEnable = mDialog.requireViewById(R.id.install_failed_blocked); break; case PackageInstaller.STATUS_FAILURE_CONFLICT: - viewToEnable = requireViewById(R.id.install_failed_conflict); + viewToEnable = mDialog.requireViewById(R.id.install_failed_conflict); break; case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE: - viewToEnable = requireViewById(R.id.install_failed_incompatible); + viewToEnable = mDialog.requireViewById(R.id.install_failed_incompatible); break; case PackageInstaller.STATUS_FAILURE_INVALID: - viewToEnable = requireViewById(R.id.install_failed_invalid_apk); + viewToEnable = mDialog.requireViewById(R.id.install_failed_invalid_apk); break; default: - viewToEnable = requireViewById(R.id.install_failed); + viewToEnable = mDialog.requireViewById(R.id.install_failed); break; } @@ -105,12 +107,18 @@ public class InstallFailed extends AlertActivity { // Store label for dialog mLabel = as.label; - mAlert.setIcon(as.icon); - mAlert.setTitle(as.label); - mAlert.setView(R.layout.install_content_view); - mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.done), - (ignored, ignored2) -> finish(), null); - setupAlert(); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + builder.setIcon(as.icon); + builder.setTitle(as.label); + builder.setView(R.layout.install_content_view); + builder.setPositiveButton(getString(R.string.done), + (ignored, ignored2) -> finish()); + builder.setOnCancelListener(dialog -> { + finish(); + }); + mDialog = builder.create(); + mDialog.show(); // Show out of space dialog if needed if (statusCode == PackageInstaller.STATUS_FAILURE_STORAGE) { diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java index 4992ef1e1c00..8d8254ad4058 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java @@ -19,6 +19,8 @@ package com.android.packageinstaller; import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_APP_SNIPPET; import static com.android.packageinstaller.PackageInstallerActivity.EXTRA_STAGED_SESSION_ID; +import android.app.Activity; +import android.app.AlertDialog; import android.app.PendingIntent; import android.content.DialogInterface; import android.content.Intent; @@ -43,7 +45,7 @@ import java.io.IOException; * <p>This has two phases: First send the data to the package manager, then wait until the package * manager processed the result.</p> */ -public class InstallInstalling extends AlertActivity { +public class InstallInstalling extends Activity { private static final String LOG_TAG = InstallInstalling.class.getSimpleName(); private static final String SESSION_ID = "com.android.packageinstaller.SESSION_ID"; @@ -67,6 +69,8 @@ public class InstallInstalling extends AlertActivity { /** The button that can cancel this dialog */ private Button mCancelButton; + private AlertDialog mDialog; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -90,10 +94,12 @@ public class InstallInstalling extends AlertActivity { PackageUtil.AppSnippet as = getIntent() .getParcelableExtra(EXTRA_APP_SNIPPET, PackageUtil.AppSnippet.class); - mAlert.setIcon(as.icon); - mAlert.setTitle(as.label); - mAlert.setView(R.layout.install_content_view); - mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + builder.setIcon(as.icon); + builder.setTitle(as.label); + builder.setView(R.layout.install_content_view); + builder.setNegativeButton(getString(R.string.cancel), (ignored, ignored2) -> { if (mInstallingTask != null) { mInstallingTask.cancel(true); @@ -106,9 +112,11 @@ public class InstallInstalling extends AlertActivity { setResult(RESULT_CANCELED); finish(); - }, null); - setupAlert(); - requireViewById(R.id.installing).setVisibility(View.VISIBLE); + }); + builder.setCancelable(false); + mDialog = builder.create(); + mDialog.show(); + mDialog.requireViewById(R.id.installing).setVisibility(View.VISIBLE); if (savedInstanceState != null) { mSessionId = savedInstanceState.getInt(SESSION_ID); @@ -145,7 +153,7 @@ public class InstallInstalling extends AlertActivity { } } - mCancelButton = mAlert.getButton(DialogInterface.BUTTON_NEGATIVE); + mCancelButton = mDialog.getButton(DialogInterface.BUTTON_NEGATIVE); } } diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java index 483fb8c451ae..cf2f85ed5356 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java @@ -52,7 +52,7 @@ import java.io.OutputStream; * If a package gets installed from a content URI this step stages the installation session * reading bytes from the URI. */ -public class InstallStaging extends AlertActivity { +public class InstallStaging extends Activity { private static final String LOG_TAG = InstallStaging.class.getSimpleName(); private static final String STAGED_SESSION_ID = "STAGED_SESSION_ID"; @@ -65,6 +65,8 @@ public class InstallStaging extends AlertActivity { /** The session the package is in */ private int mStagedSessionId; + private AlertDialog mDialog; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -72,10 +74,13 @@ public class InstallStaging extends AlertActivity { mInstaller = getPackageManager().getPackageInstaller(); setFinishOnTouchOutside(true); - mAlert.setIcon(R.drawable.ic_file_download); - mAlert.setTitle(getString(R.string.app_name_unknown)); - mAlert.setView(R.layout.install_content_view); - mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + builder.setIcon(R.drawable.ic_file_download); + builder.setTitle(getString(R.string.app_name_unknown)); + builder.setView(R.layout.install_content_view); + builder.setNegativeButton(getString(R.string.cancel), (ignored, ignored2) -> { if (mStagingTask != null) { mStagingTask.cancel(true); @@ -85,9 +90,21 @@ public class InstallStaging extends AlertActivity { setResult(RESULT_CANCELED); finish(); - }, null); - setupAlert(); - requireViewById(R.id.staging).setVisibility(View.VISIBLE); + }); + builder.setOnCancelListener(dialog -> { + if (mStagingTask != null) { + mStagingTask.cancel(true); + } + + cleanupStagingSession(); + + setResult(RESULT_CANCELED); + finish(); + }); + mDialog = builder.create(); + mDialog.show(); + mDialog.requireViewById(com.android.packageinstaller.R.id.staging) + .setVisibility(View.VISIBLE); if (savedInstanceState != null) { mStagedSessionId = savedInstanceState.getInt(STAGED_SESSION_ID, 0); @@ -275,8 +292,9 @@ public class InstallStaging extends AlertActivity { @Override protected void onPreExecute() { final long sizeBytes = getContentSizeBytes(); - - mProgressBar = sizeBytes > 0 ? requireViewById(R.id.progress_indeterminate) : null; + if (sizeBytes > 0 && mDialog != null) { + mProgressBar = mDialog.requireViewById(R.id.progress_indeterminate); + } if (mProgressBar != null) { mProgressBar.setProgress(0); mProgressBar.setMax(100); diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java index fbc9525d4615..9af88c3b4694 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java @@ -17,6 +17,7 @@ package com.android.packageinstaller; import android.app.Activity; +import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -34,7 +35,7 @@ import java.util.List; /** * Finish installation: Return status code to the caller or display "success" UI to user */ -public class InstallSuccess extends AlertActivity { +public class InstallSuccess extends Activity { private static final String LOG_TAG = InstallSuccess.class.getSimpleName(); @Nullable @@ -46,6 +47,8 @@ public class InstallSuccess extends AlertActivity { @Nullable private Intent mLaunchIntent; + private AlertDialog mDialog; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -83,20 +86,27 @@ public class InstallSuccess extends AlertActivity { return; } - mAlert.setIcon(mAppSnippet.icon); - mAlert.setTitle(mAppSnippet.label); - mAlert.setView(R.layout.install_content_view); - mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.launch), null, - null); - mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.done), + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setIcon(mAppSnippet.icon); + builder.setTitle(mAppSnippet.label); + builder.setView(R.layout.install_content_view); + builder.setPositiveButton(getString(R.string.launch), null); + builder.setNegativeButton(getString(R.string.done), (ignored, ignored2) -> { if (mAppPackageName != null) { Log.i(LOG_TAG, "Finished installing " + mAppPackageName); } finish(); - }, null); - setupAlert(); - requireViewById(R.id.install_success).setVisibility(View.VISIBLE); + }); + builder.setOnCancelListener(dialog -> { + if (mAppPackageName != null) { + Log.i(LOG_TAG, "Finished installing " + mAppPackageName); + } + finish(); + }); + mDialog = builder.create(); + mDialog.show(); + mDialog.requireViewById(R.id.install_success).setVisibility(View.VISIBLE); // Enable or disable "launch" button boolean enabled = false; if (mLaunchIntent != null) { @@ -107,7 +117,7 @@ public class InstallSuccess extends AlertActivity { } } - Button launchButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE); + Button launchButton = mDialog.getButton(DialogInterface.BUTTON_POSITIVE); if (enabled) { launchButton.setOnClickListener(view -> { setResult(Activity.RESULT_OK, mLaunchIntent); diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java index c5ae4a37b355..ceb580d170d0 100644 --- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java +++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java @@ -71,7 +71,7 @@ import java.util.List; * Based on the user response the package is then installed by launching InstallAppConfirm * sub activity. All state transitions are handled in this activity */ -public class PackageInstallerActivity extends AlertActivity { +public class PackageInstallerActivity extends Activity { private static final String TAG = "PackageInstaller"; private static final int REQUEST_TRUST_EXTERNAL_SOURCE = 1; @@ -135,11 +135,13 @@ public class PackageInstallerActivity extends AlertActivity { // Would the mOk button be enabled if this activity would be resumed private boolean mEnableOk = false; + private AlertDialog mDialog; + private void startInstallConfirm() { TextView viewToEnable; if (mAppInfo != null) { - viewToEnable = requireViewById(R.id.install_confirm_question_update); + viewToEnable = mDialog.requireViewById(R.id.install_confirm_question_update); final CharSequence existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(); final CharSequence requestedUpdateOwnerLabel = getApplicationLabel(mCallingPackage); @@ -157,7 +159,7 @@ public class PackageInstallerActivity extends AlertActivity { } } else { // This is a new application with no permissions. - viewToEnable = requireViewById(R.id.install_confirm_question); + viewToEnable = mDialog.requireViewById(R.id.install_confirm_question); } viewToEnable.setVisibility(View.VISIBLE); @@ -480,10 +482,11 @@ public class PackageInstallerActivity extends AlertActivity { } private void bindUi() { - mAlert.setIcon(mAppSnippet.icon); - mAlert.setTitle(mAppSnippet.label); - mAlert.setView(R.layout.install_content_view); - mAlert.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.install), + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setIcon(mAppSnippet.icon); + builder.setTitle(mAppSnippet.label); + builder.setView(R.layout.install_content_view); + builder.setPositiveButton(getString(R.string.install), (ignored, ignored2) -> { if (mOk.isEnabled()) { if (mSessionId != -1) { @@ -493,20 +496,26 @@ public class PackageInstallerActivity extends AlertActivity { startInstall(); } } - }, null); - mAlert.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), + }); + builder.setNegativeButton(getString(R.string.cancel), (ignored, ignored2) -> { // Cancel and finish setActivityResult(RESULT_CANCELED); finish(); - }, null); - setupAlert(); + }); + builder.setOnCancelListener(dialog -> { + // Cancel and finish + setActivityResult(RESULT_CANCELED); + finish(); + }); + mDialog = builder.create(); + mDialog.show(); - mOk = mAlert.getButton(DialogInterface.BUTTON_POSITIVE); + mOk = mDialog.getButton(DialogInterface.BUTTON_POSITIVE); mOk.setEnabled(false); if (!mOk.isInTouchMode()) { - mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).requestFocus(); + mDialog.getButton(DialogInterface.BUTTON_NEGATIVE).requestFocus(); } } diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png Binary files differindex 7c135a09d588..63efaf557c3c 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_preference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_preference.png Binary files differindex 7b438c40134c..3ac1d0f4572c 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_preference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_preference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_progressBar.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_progressBar.png Binary files differindex ac64619057b1..105d1a108620 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_progressBar.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_progressBar.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png Binary files differindex 5506c8c7854a..a038779b0e79 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_switchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_switchPreference.png Binary files differindex f4b90634b536..a042ffbdc4d0 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_switchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_switchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_twoTargetSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_twoTargetSwitchPreference.png Binary files differindex fc60c0f43513..ae0abdde0c4f 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_twoTargetSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_twoTargetSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png Binary files differindex 81a181f96f17..ae11f810c0bf 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_preference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_preference.png Binary files differindex a6200400687e..9bc2b5d3b0c7 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_preference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_preference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_progressBar.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_progressBar.png Binary files differindex 0b40aa872764..fc845a63efb4 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_progressBar.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_progressBar.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png Binary files differindex cfe8587e852b..03db688f6799 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_switchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_switchPreference.png Binary files differindex 363275527101..235df22934e7 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_switchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_switchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png Binary files differindex 7e5b602e8adb..90442080fe22 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png Binary files differindex 8a0da3130281..8333e68bfc13 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_preference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_preference.png Binary files differindex 236a1a0234d1..fcfd1d8763c1 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_preference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_preference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_progressBar.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_progressBar.png Binary files differindex 72b7954b9972..693c59243257 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_progressBar.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_progressBar.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png Binary files differindex 36486c44198a..1345c379cfb0 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_switchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_switchPreference.png Binary files differindex fedce448e970..d0d014e5f8ed 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_switchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_switchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_twoTargetSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_twoTargetSwitchPreference.png Binary files differindex 3b389d77b04d..5bd1144b4e88 100644 --- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_twoTargetSwitchPreference.png +++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_twoTargetSwitchPreference.png diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/util/SettingsScreenshotTestRule.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/util/SettingsScreenshotTestRule.kt index 1cbdc33d5a4e..ae85675ab1b8 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/util/SettingsScreenshotTestRule.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/util/SettingsScreenshotTestRule.kt @@ -94,3 +94,18 @@ class SettingsScreenshotTestRule( screenshotRule.assertBitmapAgainstGolden(view.drawIntoBitmap(), goldenIdentifier, matcher) } } + +/** Create a [SettingsScreenshotTestRule] for settings screenshot tests. */ +fun settingsScreenshotTestRule( + emulationSpec: DeviceEmulationSpec, +): SettingsScreenshotTestRule { + val assetPath = if (Build.FINGERPRINT.contains("robolectric")) { + "frameworks/base/packages/SettingsLib/Spa/screenshot/robotests/assets" + } else { + "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" + } + return SettingsScreenshotTestRule( + emulationSpec, + assetPath + ) +} diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/button/ActionButtonsScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/button/ActionButtonsScreenshotTest.kt index 2cb6044d9bb9..8f762f606f18 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/button/ActionButtonsScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/button/ActionButtonsScreenshotTest.kt @@ -20,7 +20,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.Launch import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.WarningAmber -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.button.ActionButton import com.android.settingslib.spa.widget.button.ActionButtons import org.junit.Rule @@ -42,9 +42,8 @@ class ActionButtonsScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/BarChartScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/BarChartScreenshotTest.kt index 7ef9f106a082..d766425fc12b 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/BarChartScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/BarChartScreenshotTest.kt @@ -17,7 +17,7 @@ package com.android.settingslib.spa.screenshot.widget.chart import androidx.compose.material3.MaterialTheme -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.chart.BarChart import com.android.settingslib.spa.widget.chart.BarChartData import com.android.settingslib.spa.widget.chart.BarChartModel @@ -41,9 +41,8 @@ class BarChartScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/LineChartScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/LineChartScreenshotTest.kt index 3790164612c0..495bcbcc051e 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/LineChartScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/LineChartScreenshotTest.kt @@ -16,7 +16,7 @@ package com.android.settingslib.spa.screenshot.widget.chart -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.chart.LineChart import com.android.settingslib.spa.widget.chart.LineChartData import com.android.settingslib.spa.widget.chart.LineChartModel @@ -41,9 +41,8 @@ class LineChartScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/PieChartScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/PieChartScreenshotTest.kt index 3c3cc85b135d..ee61aadd6262 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/PieChartScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/chart/PieChartScreenshotTest.kt @@ -16,7 +16,7 @@ package com.android.settingslib.spa.screenshot.widget.chart -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.chart.PieChart import com.android.settingslib.spa.widget.chart.PieChartData import com.android.settingslib.spa.widget.chart.PieChartModel @@ -39,9 +39,8 @@ class PieChartScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/illustration/ImageIllustrationScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/illustration/ImageIllustrationScreenshotTest.kt index 616b22525b09..94d032cbd507 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/illustration/ImageIllustrationScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/illustration/ImageIllustrationScreenshotTest.kt @@ -17,7 +17,7 @@ package com.android.settingslib.spa.screenshot.widget.illustration import com.android.settingslib.spa.screenshot.R -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.illustration.Illustration import com.android.settingslib.spa.widget.illustration.IllustrationModel import com.android.settingslib.spa.widget.illustration.ResourceType @@ -40,9 +40,8 @@ class ImageIllustrationScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/MainSwitchPreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/MainSwitchPreferenceScreenshotTest.kt index 8dd4ce7fec2f..2a01d8496158 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/MainSwitchPreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/MainSwitchPreferenceScreenshotTest.kt @@ -17,7 +17,7 @@ package com.android.settingslib.spa.screenshot.widget.preference import androidx.compose.foundation.layout.Column -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.MainSwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import org.junit.Rule @@ -39,9 +39,8 @@ class MainSwitchPreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/PreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/PreferenceScreenshotTest.kt index 1e1a785bea21..4d8650efe201 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/PreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/PreferenceScreenshotTest.kt @@ -21,7 +21,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Autorenew import androidx.compose.material.icons.outlined.DisabledByDefault import androidx.compose.runtime.Composable -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.Preference import com.android.settingslib.spa.widget.preference.PreferenceModel import com.android.settingslib.spa.widget.ui.SettingsIcon @@ -48,9 +48,8 @@ class PreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/ProgressBarPreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/ProgressBarPreferenceScreenshotTest.kt index d1878a744882..3983cc08ebc3 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/ProgressBarPreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/ProgressBarPreferenceScreenshotTest.kt @@ -21,7 +21,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Delete import androidx.compose.material.icons.outlined.SystemUpdate import androidx.compose.runtime.Composable -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.ProgressBarPreference import com.android.settingslib.spa.widget.preference.ProgressBarPreferenceModel import com.android.settingslib.spa.widget.preference.ProgressBarWithDataPreference @@ -45,9 +45,8 @@ class ProgressBarPreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SliderPreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SliderPreferenceScreenshotTest.kt index c9f098bd77e3..3a96a7090d9b 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SliderPreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SliderPreferenceScreenshotTest.kt @@ -19,7 +19,7 @@ package com.android.settingslib.spa.screenshot.widget.preference import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.AccessAlarm -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.SliderPreference import com.android.settingslib.spa.widget.preference.SliderPreferenceModel import org.junit.Rule @@ -41,9 +41,8 @@ class SliderPreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SwitchPreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SwitchPreferenceScreenshotTest.kt index eca40fbfee45..4a8064ac21d4 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SwitchPreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/SwitchPreferenceScreenshotTest.kt @@ -20,7 +20,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.AirplanemodeActive import androidx.compose.runtime.Composable -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.ui.SettingsIcon @@ -43,9 +43,8 @@ class SwitchPreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/TwoTargetSwitchPreferenceScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/TwoTargetSwitchPreferenceScreenshotTest.kt index f81a59fef79c..91b7b2429fca 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/TwoTargetSwitchPreferenceScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/preference/TwoTargetSwitchPreferenceScreenshotTest.kt @@ -18,7 +18,7 @@ package com.android.settingslib.spa.screenshot.widget.preference import androidx.compose.foundation.layout.Column import com.android.settingslib.spa.framework.compose.stateOf -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference import org.junit.Rule @@ -40,9 +40,8 @@ class TwoTargetSwitchPreferenceScreenshotTest(emulationSpec: DeviceEmulationSpec @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/FooterScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/FooterScreenshotTest.kt index 98a4288d7e53..6ba010f5f96f 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/FooterScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/FooterScreenshotTest.kt @@ -16,7 +16,7 @@ package com.android.settingslib.spa.screenshot.widget.ui -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.ui.Footer import org.junit.Rule import org.junit.Test @@ -37,9 +37,8 @@ class FooterScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/SpinnerScreenshotTest.kt b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/SpinnerScreenshotTest.kt index 5417095260f3..320b20703c38 100644 --- a/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/SpinnerScreenshotTest.kt +++ b/packages/SettingsLib/Spa/screenshot/src/com/android/settingslib/spa/screenshot/widget/ui/SpinnerScreenshotTest.kt @@ -16,7 +16,7 @@ package com.android.settingslib.spa.screenshot.widget.ui -import com.android.settingslib.spa.screenshot.util.SettingsScreenshotTestRule +import com.android.settingslib.spa.screenshot.util.settingsScreenshotTestRule import com.android.settingslib.spa.widget.ui.Spinner import com.android.settingslib.spa.widget.ui.SpinnerOption import org.junit.Rule @@ -38,9 +38,8 @@ class SpinnerScreenshotTest(emulationSpec: DeviceEmulationSpec) { @get:Rule val screenshotRule = - SettingsScreenshotTestRule( + settingsScreenshotTestRule( emulationSpec, - "frameworks/base/packages/SettingsLib/Spa/screenshot/assets" ) @Test diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt index 352503742b9c..5baf7be98666 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt @@ -16,20 +16,22 @@ package com.android.settingslib.spaprivileged.model.enterprise -import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_CATEGORY_HEADER import android.app.admin.DevicePolicyResources.Strings.Settings.PRIVATE_CATEGORY_HEADER import android.app.admin.DevicePolicyResources.Strings.Settings.WORK_CATEGORY_HEADER import android.content.Context import android.content.pm.UserInfo import com.android.settingslib.R +import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager -class EnterpriseRepository(private val context: Context) { - private val resources by lazy { - checkNotNull(context.getSystemService(DevicePolicyManager::class.java)).resources - } +interface IEnterpriseRepository { + fun getEnterpriseString(updatableStringId: String, resId: Int): String +} + +class EnterpriseRepository(private val context: Context) : IEnterpriseRepository { + private val resources by lazy { context.devicePolicyManager.resources } - fun getEnterpriseString(updatableStringId: String, resId: Int): String = + override fun getEnterpriseString(updatableStringId: String, resId: Int): String = checkNotNull(resources.getString(updatableStringId) { context.getString(resId) }) fun getProfileTitle(userInfo: UserInfo): String = if (userInfo.isManagedProfile) { diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt new file mode 100644 index 000000000000..3acc9ad83d2c --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.model.enterprise + +import android.app.admin.DevicePolicyResources.Strings.Settings +import android.content.Context +import com.android.settingslib.RestrictedLockUtils +import com.android.settingslib.widget.restricted.R + +sealed interface RestrictedMode + +data object NoRestricted : RestrictedMode + +data object BaseUserRestricted : RestrictedMode + +interface BlockedByAdmin : RestrictedMode { + fun getSummary(checked: Boolean?): String + fun sendShowAdminSupportDetailsIntent() +} + +internal data class BlockedByAdminImpl( + private val context: Context, + private val enforcedAdmin: RestrictedLockUtils.EnforcedAdmin, + private val enterpriseRepository: IEnterpriseRepository = EnterpriseRepository(context), +) : BlockedByAdmin { + override fun getSummary(checked: Boolean?) = when (checked) { + true -> enterpriseRepository.getEnterpriseString( + updatableStringId = Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY, + resId = R.string.enabled_by_admin, + ) + + false -> enterpriseRepository.getEnterpriseString( + updatableStringId = Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY, + resId = R.string.disabled_by_admin, + ) + + else -> "" + } + + override fun sendShowAdminSupportDetailsIntent() { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin) + } +} diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt index 09cb98e22af3..550966beb0b8 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt @@ -16,7 +16,6 @@ package com.android.settingslib.spaprivileged.model.enterprise -import android.app.admin.DevicePolicyResources.Strings.Settings import android.content.Context import android.os.UserHandle import android.os.UserManager @@ -25,55 +24,16 @@ import androidx.compose.runtime.State import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.android.settingslib.RestrictedLockUtils -import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin import com.android.settingslib.RestrictedLockUtilsInternal import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn -import com.android.settingslib.widget.restricted.R data class Restrictions( val userId: Int = UserHandle.myUserId(), val keys: List<String>, ) -sealed interface RestrictedMode - -data object NoRestricted : RestrictedMode - -data object BaseUserRestricted : RestrictedMode - -interface BlockedByAdmin : RestrictedMode { - fun getSummary(checked: Boolean?): String - fun sendShowAdminSupportDetailsIntent() -} - -private data class BlockedByAdminImpl( - private val context: Context, - private val enforcedAdmin: EnforcedAdmin, -) : BlockedByAdmin { - private val enterpriseRepository by lazy { EnterpriseRepository(context) } - - override fun getSummary(checked: Boolean?) = when (checked) { - true -> enterpriseRepository.getEnterpriseString( - updatableStringId = Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY, - resId = R.string.enabled_by_admin, - ) - - false -> enterpriseRepository.getEnterpriseString( - updatableStringId = Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY, - resId = R.string.disabled_by_admin, - ) - - else -> "" - } - - override fun sendShowAdminSupportDetailsIntent() { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin) - } -} - interface RestrictionsProvider { @Composable fun restrictedModeState(): State<RestrictedMode?> diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt index 7bd7fbe0c526..06b3eabfad26 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt @@ -16,9 +16,7 @@ package com.android.settingslib.spaprivileged.template.app -import android.app.AppOpsManager.MODE_ALLOWED -import android.app.AppOpsManager.MODE_DEFAULT -import android.app.AppOpsManager.MODE_ERRORED +import android.app.AppOpsManager import android.content.Context import android.content.pm.ApplicationInfo import androidx.compose.runtime.Composable @@ -64,7 +62,7 @@ abstract class AppOpPermissionListModel( */ open val permissionHasAppOpFlag: Boolean = true - open val modeForNotAllowed: Int = MODE_ERRORED + open val modeForNotAllowed: Int = AppOpsManager.MODE_ERRORED /** * Use AppOpsManager#setUidMode() instead of AppOpsManager#setMode() when set allowed. @@ -130,27 +128,14 @@ abstract class AppOpPermissionListModel( override fun filter(userIdFlow: Flow<Int>, recordListFlow: Flow<List<AppOpPermissionRecord>>) = recordListFlow.filterItem(::isChangeable) - /** - * Defining the default behavior as permissible as long as the package requested this permission - * (This means pre-M gets approval during install time; M apps gets approval during runtime). - */ @Composable - override fun isAllowed(record: AppOpPermissionRecord): () -> Boolean? { - if (record.hasRequestBroaderPermission) { - // Broader permission trumps the specific permission. - return { true } - } - - val mode = record.appOpsController.mode.observeAsState() - return { - when (mode.value) { - null -> null - MODE_ALLOWED -> true - MODE_DEFAULT -> with(packageManagers) { record.app.hasGrantPermission(permission) } - else -> false - } - } - } + override fun isAllowed(record: AppOpPermissionRecord): () -> Boolean? = + isAllowed( + record = record, + appOpsController = record.appOpsController, + permission = permission, + packageManagers = packageManagers, + ) override fun isChangeable(record: AppOpPermissionRecord) = record.hasRequestPermission && @@ -161,3 +146,33 @@ abstract class AppOpPermissionListModel( record.appOpsController.setAllowed(newAllowed) } } + +/** + * Defining the default behavior as permissible as long as the package requested this permission + * (This means pre-M gets approval during install time; M apps gets approval during runtime). + */ +@Composable +internal fun isAllowed( + record: AppOpPermissionRecord, + appOpsController: IAppOpsController, + permission: String, + packageManagers: IPackageManagers = PackageManagers, +): () -> Boolean? { + if (record.hasRequestBroaderPermission) { + // Broader permission trumps the specific permission. + return { true } + } + + val mode = appOpsController.mode.observeAsState() + return { + when (mode.value) { + null -> null + AppOpsManager.MODE_ALLOWED -> true + AppOpsManager.MODE_DEFAULT -> { + with(packageManagers) { record.app.hasGrantPermission(permission) } + } + + else -> false + } + } +} diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt index 3380b7db4cd0..565543614866 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt @@ -16,19 +16,16 @@ package com.android.settingslib.spaprivileged.template.app -import android.content.Context import android.content.pm.ApplicationInfo import android.os.Bundle import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.core.os.bundleOf +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavType import androidx.navigation.navArgument import com.android.settingslib.spa.framework.common.SettingsEntry @@ -49,6 +46,8 @@ import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvid import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn internal class TogglePermissionAppInfoPageProvider( private val appListTemplate: TogglePermissionAppListTemplate, @@ -132,7 +131,7 @@ internal fun <T : AppRecord> TogglePermissionAppListModel<T>.TogglePermissionApp @VisibleForTesting @Composable -internal fun TogglePermissionAppListModel<out AppRecord>.TogglePermissionAppInfoPage( +internal fun <T : AppRecord> TogglePermissionAppListModel<T>.TogglePermissionAppInfoPage( packageName: String, userId: Int, packageManagers: IPackageManagers = PackageManagers, @@ -145,40 +144,34 @@ internal fun TogglePermissionAppListModel<out AppRecord>.TogglePermissionAppInfo footerContent = { AnnotatedText(footerResId) }, packageManagers = packageManagers, ) { - val model = createSwitchModel(checkNotNull(applicationInfo)) + val app = applicationInfo ?: return@AppInfoPage + val record = rememberRecord(app).value ?: return@AppInfoPage + val isAllowed = isAllowed(record) + val isChangeable by rememberIsChangeable(record) + val switchModel = object : SwitchPreferenceModel { + override val title = stringResource(switchTitleResId) + override val checked = isAllowed + override val changeable = { isChangeable } + override val onCheckedChange: (Boolean) -> Unit = { setAllowed(record, it) } + } val restrictions = Restrictions(userId, switchRestrictionKeys) - RestrictedSwitchPreference(model, restrictions, restrictionsProviderFactory) + RestrictedSwitchPreference(switchModel, restrictions, restrictionsProviderFactory) } } @Composable -private fun <T : AppRecord> TogglePermissionAppListModel<T>.createSwitchModel( - app: ApplicationInfo, -): TogglePermissionSwitchModel<T> { - val context = LocalContext.current - val record = remember(app) { transformItem(app) } - val isAllowed = isAllowed(record) - return remember(record) { TogglePermissionSwitchModel(context, this, record, isAllowed) } - .also { model -> LaunchedEffect(model, Dispatchers.IO) { model.initState() } } -} - -private class TogglePermissionSwitchModel<T : AppRecord>( - context: Context, - private val listModel: TogglePermissionAppListModel<T>, - private val record: T, - isAllowed: () -> Boolean?, -) : SwitchPreferenceModel { - private var appChangeable by mutableStateOf(true) +private fun <T : AppRecord> TogglePermissionAppListModel<T>.rememberRecord(app: ApplicationInfo) = + remember(app) { + flow { + emit(transformItem(app)) + }.flowOn(Dispatchers.Default) + }.collectAsStateWithLifecycle(initialValue = null) - override val title: String = context.getString(listModel.switchTitleResId) - override val checked = isAllowed - override val changeable = { appChangeable } - fun initState() { - appChangeable = listModel.isChangeable(record) - } - - override val onCheckedChange: (Boolean) -> Unit = { newChecked -> - listModel.setAllowed(record, newChecked) - } -} +@Composable +private fun <T : AppRecord> TogglePermissionAppListModel<T>.rememberIsChangeable(record: T) = + remember(record) { + flow { + emit(isChangeable(record)) + }.flowOn(Dispatchers.Default) + }.collectAsStateWithLifecycle(initialValue = false) diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt new file mode 100644 index 000000000000..8fd16b37bfeb --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spaprivileged.model.enterprise + +import android.app.admin.DevicePolicyResources.Strings.Settings +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.RestrictedLockUtils +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RestrictedModeTest { + private val context: Context = ApplicationProvider.getApplicationContext() + + private val fakeEnterpriseRepository = object : IEnterpriseRepository { + override fun getEnterpriseString(updatableStringId: String, resId: Int): String = + when (updatableStringId) { + Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY -> ENABLED_BY_ADMIN + Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY -> DISABLED_BY_ADMIN + else -> "" + } + } + + @Test + fun blockedByAdmin_getSummaryWhenChecked() { + val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, fakeEnterpriseRepository) + + val summary = blockedByAdmin.getSummary(true) + + assertThat(summary).isEqualTo(ENABLED_BY_ADMIN) + } + + @Test + fun blockedByAdmin_getSummaryNotWhenChecked() { + val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, fakeEnterpriseRepository) + + val summary = blockedByAdmin.getSummary(false) + + assertThat(summary).isEqualTo(DISABLED_BY_ADMIN) + } + + private companion object { + const val RESTRICTION = "restriction" + val ENFORCED_ADMIN: RestrictedLockUtils.EnforcedAdmin = + RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION) + + const val ENABLED_BY_ADMIN = "Enabled by admin" + const val DISABLED_BY_ADMIN = "Disabled by admin" + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt index 3b2fe0f5c16b..d158a2414f85 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppListTest.kt @@ -32,44 +32,37 @@ import com.android.settingslib.spaprivileged.test.R import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest -import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Spy -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule import org.mockito.kotlin.any import org.mockito.kotlin.doNothing +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class AppOpPermissionAppListTest { - @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() + @get:Rule + val composeTestRule = createComposeRule() - @get:Rule val composeTestRule = createComposeRule() + private val packageManagers = mock<IPackageManagers>() - @Spy private val context: Context = ApplicationProvider.getApplicationContext() + private val appOpsManager = mock<AppOpsManager>() - @Mock private lateinit var packageManagers: IPackageManagers - - @Mock private lateinit var appOpsManager: AppOpsManager - - @Mock private lateinit var packageManager: PackageManager - - private lateinit var listModel: TestAppOpPermissionAppListModel + private val packageManager = mock<PackageManager> { + doNothing().whenever(mock).updatePermissionFlags(any(), any(), any(), any(), any()) + } - @Before - fun setUp() { - whenever(context.appOpsManager).thenReturn(appOpsManager) - whenever(context.packageManager).thenReturn(packageManager) - doNothing().whenever(packageManager) - .updatePermissionFlags(any(), any(), any(), any(), any()) - listModel = TestAppOpPermissionAppListModel() + private val context: Context = spy(ApplicationProvider.getApplicationContext()) { + on { appOpsManager } doReturn appOpsManager + on { packageManager } doReturn packageManager } + private val listModel = TestAppOpPermissionAppListModel() + @Test fun transformItem_recordHasCorrectApp() { val record = listModel.transformItem(APP) diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt index 8bfae14b3b8f..270b3faa7ec6 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt @@ -38,44 +38,34 @@ import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsPro import com.android.settingslib.spaprivileged.tests.testutils.TestTogglePermissionAppListModel import com.android.settingslib.spaprivileged.tests.testutils.TestTogglePermissionAppListProvider import com.google.common.truth.Truth.assertThat -import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoRule -import org.mockito.kotlin.whenever +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock @RunWith(AndroidJUnit4::class) class TogglePermissionAppInfoPageTest { @get:Rule val composeTestRule = createComposeRule() - @get:Rule - val mockito: MockitoRule = MockitoJUnit.rule() - private val context: Context = ApplicationProvider.getApplicationContext() - @Mock - private lateinit var packageManagers: IPackageManagers + private val packageManagers = mock<IPackageManagers> { + on { getPackageInfoAsUser(PACKAGE_NAME, USER_ID) } doReturn PACKAGE_INFO + } private val fakeNavControllerWrapper = FakeNavControllerWrapper() - private val fakeRestrictionsProvider = FakeRestrictionsProvider() + private val fakeRestrictionsProvider = FakeRestrictionsProvider().apply { + restrictedMode = NoRestricted + } private val appListTemplate = TogglePermissionAppListTemplate(listOf(TestTogglePermissionAppListProvider)) private val appInfoPageProvider = TogglePermissionAppInfoPageProvider(appListTemplate) - @Before - fun setUp() { - fakeRestrictionsProvider.restrictedMode = NoRestricted - whenever(packageManagers.getPackageInfoAsUser(PACKAGE_NAME, USER_ID)) - .thenReturn(PACKAGE_INFO) - } - @Test fun buildEntry() { val entryList = appInfoPageProvider.buildEntry(null) diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index ea744688f21a..de703e98bf34 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -437,8 +437,8 @@ <string name="transcode_notification" msgid="5560515979793436168">"Паказваць апавяшчэнні пра перакадзіраванне"</string> <string name="transcode_disable_cache" msgid="3160069309377467045">"Адключыць кэш перакадзіравання"</string> <string name="widevine_settings_title" msgid="4023329801172572917">"Налады Widevine"</string> - <string name="force_l3_fallback_title" msgid="4987972688770202547">"Прымусовае выкарыстанне альтэрнатывы L3"</string> - <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Выберыце, ці трэба прымусова выкарыстоўваць альтэрнатыву L3"</string> + <string name="force_l3_fallback_title" msgid="4987972688770202547">"Прымусовы пераход на ўзровень бяспекі 3"</string> + <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Выберыце, каб прымусова пераходзіць на ўзровень бяспекі 3"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Запушчаныя службы"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Прагляд запушчаных службаў i кіраванне iмi"</string> <string name="select_webview_provider_title" msgid="3917815648099445503">"Рэалізацыя WebView"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index e35754326b5f..0a99650ce990 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -437,7 +437,7 @@ <string name="transcode_notification" msgid="5560515979793436168">"Хөрвүүлгийн мэдэгдэл харуулах"</string> <string name="transcode_disable_cache" msgid="3160069309377467045">"Хөрвүүлгийн завсрын санах ойг идэвхгүй болгох"</string> <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-н тохиргоо"</string> - <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 нөөцийг хүчилнэ үү"</string> + <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 нөөцийг хүчлэх"</string> <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 нөөцийг хүчлэхийг сонгоно уу"</string> <string name="runningservices_settings_title" msgid="6460099290493086515">"Ажиллаж байгаа үйлчилгээнүүд"</string> <string name="runningservices_settings_summary" msgid="1046080643262665743">"Одоо ажиллаж байгаа үйлчилгээнүүдийг харах болон хянах"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index f5bacb62b6b2..c97445f04eea 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -230,30 +230,30 @@ public class BluetoothEventManager { @VisibleForTesting void dispatchActiveDeviceChanged( - @Nullable CachedBluetoothDevice activeDevice, - int bluetoothProfile) { + @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) { + CachedBluetoothDevice targetDevice = activeDevice; for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) { - Set<CachedBluetoothDevice> memberSet = cachedDevice.getMemberDevice(); - boolean isActive = Objects.equals(cachedDevice, activeDevice); - if (!isActive && !memberSet.isEmpty()) { - for (CachedBluetoothDevice memberCachedDevice : memberSet) { - isActive = Objects.equals(memberCachedDevice, activeDevice); - if (isActive) { - Log.d(TAG, - "The active device is the member device " - + activeDevice.getDevice().getAnonymizedAddress() - + ". change activeDevice as main device " - + cachedDevice.getDevice().getAnonymizedAddress()); - activeDevice = cachedDevice; - break; - } - } + // should report isActive from main device or it will cause trouble to other callers. + CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); + CachedBluetoothDevice finalTargetDevice = targetDevice; + if (targetDevice != null + && ((subDevice != null && subDevice.equals(targetDevice)) + || cachedDevice.getMemberDevice().stream().anyMatch( + memberDevice -> memberDevice.equals(finalTargetDevice)))) { + Log.d(TAG, + "The active device is the sub/member device " + + targetDevice.getDevice().getAnonymizedAddress() + + ". change targetDevice as main device " + + cachedDevice.getDevice().getAnonymizedAddress()); + targetDevice = cachedDevice; } - cachedDevice.onActiveDeviceChanged(isActive, bluetoothProfile); + boolean isActiveDevice = cachedDevice.equals(targetDevice); + cachedDevice.onActiveDeviceChanged(isActiveDevice, bluetoothProfile); mDeviceManager.onActiveDeviceChanged(cachedDevice); } + for (BluetoothCallback callback : mCallbacks) { - callback.onActiveDeviceChanged(activeDevice, bluetoothProfile); + callback.onActiveDeviceChanged(targetDevice, bluetoothProfile); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java index 8c316d1c4f21..13635c3a8256 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java @@ -412,6 +412,21 @@ public class BluetoothEventManagerTest { } @Test + public void dispatchActiveDeviceChanged_activeFromSubDevice_mainCachedDeviceActive() { + CachedBluetoothDevice subDevice = new CachedBluetoothDevice(mContext, mLocalProfileManager, + mDevice3); + mCachedDevice1.setSubDevice(subDevice); + when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn( + Collections.singletonList(mCachedDevice1)); + mCachedDevice1.onProfileStateChanged(mHearingAidProfile, + BluetoothProfile.STATE_CONNECTED); + + assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse(); + mBluetoothEventManager.dispatchActiveDeviceChanged(subDevice, BluetoothProfile.HEARING_AID); + assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue(); + } + + @Test public void showUnbondMessage_reasonAuthTimeout_showCorrectedErrorCode() { mIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mBluetoothDevice); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index ed03d94b44c0..650319fd58f9 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -19,6 +19,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.shell" coreApp="true" + updatableSystem="false" android:sharedUserId="android.uid.shell" > @@ -325,6 +326,7 @@ <uses-permission android:name="android.permission.CONTROL_KEYGUARD" /> <uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS" /> <uses-permission android:name="android.permission.SUSPEND_APPS" /> + <uses-permission android:name="android.permission.QUARANTINE_APPS" /> <uses-permission android:name="android.permission.OBSERVE_APP_USAGE" /> <uses-permission android:name="android.permission.READ_CLIPBOARD_IN_BACKGROUND" /> <!-- Permission needed to wipe the device for Test Harness Mode --> @@ -867,6 +869,8 @@ <!-- Permissions required for CTS test - CtsVoiceInteractionTestCases --> <uses-permission android:name="android.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT" /> <uses-permission android:name="android.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA" /> + <uses-permission android:name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO" /> + <uses-permission android:name="android.permission.GET_BINDING_UID_IMPORTANCE" /> <application diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index f1ffa66ae77a..d78038ecee61 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -602,6 +602,7 @@ android_robolectric_test { ":SystemUI-tests-multivalent", ], static_libs: [ + "dagger2", "androidx.test.uiautomator_uiautomator", "androidx.core_core-animation-testing", "androidx.test.ext.junit", diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index e340209afbb8..68d4b6319b2f 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -61,6 +61,13 @@ flag { } flag { + name: "notification_throttle_hun" + namespace: "systemui" + description: "During notification avalanche, throttle HUNs showing in fast succession." + bug: "307288824" +} + +flag { name: "scene_container" namespace: "systemui" description: "Enables the scene container framework go/flexiglass." @@ -119,4 +126,18 @@ flag { description: "Adds thread-local data to System UI's global coroutine scopes to " "allow for tracing of coroutine continuations using System UI's tracinglib" bug: "289353932" +} + +flag { + name: "new_aod_transition" + namespace: "systemui" + description: "New LOCKSCREEN <=> AOD transition" + bug: "301915812" +} + +flag { + name: "light_reveal_migration" + namespace: "systemui" + description: "Move LightRevealScrim to recommended architecture" + bug: "281655028" }
\ No newline at end of file diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt index ddd1c67bd5fa..914e5f2c17bf 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -22,7 +22,7 @@ import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.lifecycle.LifecycleOwner -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.people.ui.viewmodel.PeopleViewModel import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene @@ -47,6 +47,14 @@ object ComposeFacade : BaseComposeFacade { throwComposeUnavailableError() } + override fun setCommunalEditWidgetActivityContent( + activity: ComponentActivity, + viewModel: BaseCommunalViewModel, + onOpenWidgetPicker: () -> Unit, + ) { + throwComposeUnavailableError() + } + override fun createFooterActionsView( context: Context, viewModel: FooterActionsViewModel, @@ -67,12 +75,12 @@ object ComposeFacade : BaseComposeFacade { override fun createCommunalView( context: Context, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, ): View { throwComposeUnavailableError() } - override fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View { + override fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View { throwComposeUnavailableError() } diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt index eeda6c63b68f..59bd95bd9027 100644 --- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeFacade.kt @@ -32,7 +32,7 @@ import com.android.systemui.common.ui.compose.windowinsets.DisplayCutout import com.android.systemui.common.ui.compose.windowinsets.DisplayCutoutProvider import com.android.systemui.communal.ui.compose.CommunalContainer import com.android.systemui.communal.ui.compose.CommunalHub -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.people.ui.compose.PeopleScreen import com.android.systemui.people.ui.viewmodel.PeopleViewModel import com.android.systemui.qs.footer.ui.compose.FooterActions @@ -62,6 +62,21 @@ object ComposeFacade : BaseComposeFacade { activity.setContent { PlatformTheme { PeopleScreen(viewModel, onResult) } } } + override fun setCommunalEditWidgetActivityContent( + activity: ComponentActivity, + viewModel: BaseCommunalViewModel, + onOpenWidgetPicker: () -> Unit, + ) { + activity.setContent { + PlatformTheme { + CommunalHub( + viewModel = viewModel, + onOpenWidgetPicker = onOpenWidgetPicker, + ) + } + } + } + override fun createFooterActionsView( context: Context, viewModel: FooterActionsViewModel, @@ -98,14 +113,14 @@ object ComposeFacade : BaseComposeFacade { override fun createCommunalView( context: Context, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, ): View { return ComposeView(context).apply { setContent { PlatformTheme { CommunalHub(viewModel = viewModel) } } } } - override fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View { + override fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View { return ComposeView(context).apply { setContent { PlatformTheme { CommunalContainer(viewModel = viewModel) } } } 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 09706bed1921..ce84c19a53ee 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 @@ -32,7 +32,7 @@ import com.android.compose.animation.scene.Swipe import com.android.compose.animation.scene.SwipeDirection import com.android.compose.animation.scene.transitions import com.android.systemui.communal.shared.model.CommunalSceneKey -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import kotlinx.coroutines.flow.transform object Communal { @@ -59,7 +59,7 @@ val sceneTransitions = transitions { @Composable fun CommunalContainer( modifier: Modifier = Modifier, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, ) { val currentScene: SceneKey by viewModel.currentScene @@ -129,7 +129,7 @@ private fun BlankScene( /** Scene containing the glanceable hub UI. */ @Composable private fun SceneScope.CommunalScene( - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier, ) { Box(modifier.element(Communal.Elements.Content)) { CommunalHub(viewModel = viewModel) } 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 c80902e22a56..2ba1b77fb76e 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 @@ -34,6 +34,7 @@ import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Edit import androidx.compose.material3.Card import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -51,7 +52,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.shared.model.CommunalContentSize -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.media.controls.ui.MediaHostState import com.android.systemui.res.R @@ -59,7 +60,8 @@ import com.android.systemui.res.R @Composable fun CommunalHub( modifier: Modifier = Modifier, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, + onOpenWidgetPicker: (() -> Unit)? = null, ) { val communalContent by viewModel.communalContent.collectAsState(initial = emptyList()) Box( @@ -81,7 +83,7 @@ fun CommunalHub( modifier = Modifier.fillMaxHeight().width(Dimensions.CardWidth), model = communalContent[index], viewModel = viewModel, - deleteOnClick = viewModel::onDeleteWidget, + deleteOnClick = if (viewModel.isEditMode) viewModel::onDeleteWidget else null, size = SizeF( Dimensions.CardWidth.value, @@ -90,8 +92,14 @@ fun CommunalHub( ) } } - IconButton(onClick = viewModel::onOpenWidgetEditor) { - Icon(Icons.Default.Add, stringResource(R.string.button_to_open_widget_editor)) + if (viewModel.isEditMode && onOpenWidgetPicker != null) { + IconButton(onClick = onOpenWidgetPicker) { + Icon(Icons.Default.Add, stringResource(R.string.hub_mode_add_widget_button_text)) + } + } else { + IconButton(onClick = viewModel::onOpenWidgetEditor) { + Icon(Icons.Default.Edit, stringResource(R.string.button_to_open_widget_editor)) + } } // This spacer covers the edge of the LazyHorizontalGrid and prevents it from receiving @@ -109,9 +117,9 @@ fun CommunalHub( @Composable private fun CommunalContent( model: CommunalContentModel, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, size: SizeF, - deleteOnClick: (id: Int) -> Unit, + deleteOnClick: ((id: Int) -> Unit)?, modifier: Modifier = Modifier, ) { when (model) { @@ -126,19 +134,22 @@ private fun CommunalContent( private fun WidgetContent( model: CommunalContentModel.Widget, size: SizeF, - deleteOnClick: (id: Int) -> Unit, + deleteOnClick: ((id: Int) -> Unit)?, modifier: Modifier = Modifier, ) { // TODO(b/309009246): update background color Box( modifier = modifier.fillMaxSize().background(Color.White), ) { - IconButton(onClick = { deleteOnClick(model.appWidgetId) }) { - Icon( - Icons.Default.Close, - LocalContext.current.getString(R.string.button_to_remove_widget) - ) + if (deleteOnClick != null) { + IconButton(onClick = { deleteOnClick(model.appWidgetId) }) { + Icon( + Icons.Default.Close, + LocalContext.current.getString(R.string.button_to_remove_widget) + ) + } } + AndroidView( modifier = modifier, factory = { context -> @@ -146,8 +157,6 @@ private fun WidgetContent( .createView(context, model.appWidgetId, model.providerInfo) .apply { updateAppWidgetSize(Bundle.EMPTY, listOf(size)) } }, - // For reusing composition in lazy lists. - onReset = {} ) } } @@ -173,7 +182,7 @@ private fun TutorialContent(modifier: Modifier = Modifier) { } @Composable -private fun Umo(viewModel: CommunalViewModel, modifier: Modifier = Modifier) { +private fun Umo(viewModel: BaseCommunalViewModel, modifier: Modifier = Modifier) { AndroidView( modifier = modifier, factory = { 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 ee310ab41373..cc95a4b72731 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 @@ -33,6 +33,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Rect import androidx.compose.ui.graphics.toComposeRect import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.Layout import androidx.compose.ui.viewinterop.AndroidView import androidx.core.view.isVisible import com.android.compose.animation.scene.SceneScope @@ -41,6 +42,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.qualifiers.KeyguardRootView import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel +import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.res.R import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge @@ -88,7 +90,7 @@ constructor( ) { LockscreenScene( viewProvider = viewProvider, - longPressViewModel = viewModel.longPress, + viewModel = viewModel, modifier = modifier, ) } @@ -108,9 +110,9 @@ constructor( } @Composable -private fun LockscreenScene( +private fun SceneScope.LockscreenScene( viewProvider: () -> View, - longPressViewModel: KeyguardLongPressViewModel, + viewModel: LockscreenSceneViewModel, modifier: Modifier = Modifier, ) { fun findSettingsMenu(): View { @@ -121,7 +123,7 @@ private fun LockscreenScene( modifier = modifier, ) { LongPressSurface( - viewModel = longPressViewModel, + viewModel = viewModel.longPress, isSettingsMenuVisible = { findSettingsMenu().isVisible }, settingsMenuBounds = { val bounds = android.graphics.Rect() @@ -141,6 +143,28 @@ private fun LockscreenScene( }, modifier = Modifier.fillMaxSize(), ) + + val notificationStackPosition by + viewModel.keyguardRoot.notificationPositionOnLockscreen.collectAsState() + + Layout( + modifier = Modifier.fillMaxSize(), + content = { + NotificationStack( + viewModel = viewModel.notifications, + isScrimVisible = false, + ) + } + ) { measurables, constraints -> + check(measurables.size == 1) + val height = notificationStackPosition.height.toInt() + val childConstraints = constraints.copy(minHeight = height, maxHeight = height) + val placeable = measurables[0].measure(childConstraints) + layout(constraints.maxWidth, constraints.maxHeight) { + val start = (constraints.maxWidth - placeable.measuredWidth) / 2 + placeable.placeRelative(x = start, y = notificationStackPosition.top.toInt()) + } + } } } 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 dd71dfa0b008..c9d31fdcb8e5 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 @@ -17,56 +17,197 @@ package com.android.systemui.notifications.ui.composable +import android.util.Log import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue 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.layout.LayoutCoordinates +import androidx.compose.ui.layout.boundsInWindow +import androidx.compose.ui.layout.onPlaced +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.layout.positionInWindow +import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope +import com.android.compose.animation.scene.ValueKey +import com.android.compose.animation.scene.animateSharedFloatAsState +import com.android.systemui.notifications.ui.composable.Notifications.Form +import com.android.systemui.notifications.ui.composable.Notifications.SharedValues.SharedExpansionValue +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel object Notifications { object Elements { - val Notifications = ElementKey("Notifications") + val NotificationScrim = ElementKey("NotificationScrim") + val NotificationPlaceholder = ElementKey("NotificationPlaceholder") + val ShelfSpace = ElementKey("ShelfSpace") + } + + object SharedValues { + val SharedExpansionValue = ValueKey("SharedExpansionValue") + } + + enum class Form { + HunFromTop, + Stack, + HunFromBottom, } } +/** + * Adds the space where heads up notifications can appear in the scene. This should generally be the + * entire size of the scene. + */ @Composable -fun SceneScope.Notifications( +fun SceneScope.HeadsUpNotificationSpace( + viewModel: NotificationsPlaceholderViewModel, + isPeekFromBottom: Boolean = false, modifier: Modifier = Modifier, ) { - // TODO(b/272779828): implement. - Column( + NotificationPlaceholder( + viewModel = viewModel, + form = if (isPeekFromBottom) Form.HunFromBottom else Form.HunFromTop, + modifier = modifier, + ) +} + +/** Adds the space where notification stack will appear in the scene. */ +@Composable +fun SceneScope.NotificationStack( + viewModel: NotificationsPlaceholderViewModel, + isScrimVisible: Boolean, + modifier: Modifier = Modifier, +) { + Box(modifier = modifier) { + if (isScrimVisible) { + Box( + modifier = + Modifier.element(Notifications.Elements.NotificationScrim) + .fillMaxSize() + .clip(RoundedCornerShape(32.dp)) + .background(MaterialTheme.colorScheme.surface) + ) + } + NotificationPlaceholder( + viewModel = viewModel, + form = Form.Stack, + modifier = Modifier.fillMaxSize(), + ) + } +} + +/** + * This may be added to the lockscreen to provide a space to the start of the lock icon where the + * short shelf has room to flow vertically below the lock icon, but to its start, allowing more + * notifications to fit in the stack itself. (see: b/213934746) + * + * NOTE: this is totally unused for now; it is here to clarify the future plan + */ +@Composable +fun SceneScope.NotificationShelfSpace( + viewModel: NotificationsPlaceholderViewModel, + modifier: Modifier = Modifier, +) { + Text( + text = "Shelf Space", + modifier + .element(key = Notifications.Elements.ShelfSpace) + .fillMaxWidth() + .onSizeChanged { size: IntSize -> + debugLog(viewModel) { "SHELF onSizeChanged: size=$size" } + } + .onPlaced { coordinates: LayoutCoordinates -> + debugLog(viewModel) { + ("SHELF onPlaced:" + + " size=${coordinates.size}" + + " position=${coordinates.positionInWindow()}" + + " bounds=${coordinates.boundsInWindow()}") + } + } + .clip(RoundedCornerShape(24.dp)) + .background(MaterialTheme.colorScheme.primaryContainer) + .padding(16.dp), + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onPrimaryContainer, + ) +} + +@Composable +private fun SceneScope.NotificationPlaceholder( + viewModel: NotificationsPlaceholderViewModel, + form: Form, + modifier: Modifier = Modifier, +) { + val key = Notifications.Elements.NotificationPlaceholder + Box( modifier = modifier - .element(key = Notifications.Elements.Notifications) - .fillMaxWidth() - .defaultMinSize(minHeight = 300.dp) - .clip(RoundedCornerShape(32.dp)) - .background(MaterialTheme.colorScheme.surface) - .padding(16.dp), + .element(key) + .debugBackground(viewModel) + .onSizeChanged { size: IntSize -> + debugLog(viewModel) { "STACK onSizeChanged: size=$size" } + } + .onPlaced { coordinates: LayoutCoordinates -> + debugLog(viewModel) { + "STACK onPlaced:" + + " size=${coordinates.size}" + + " position=${coordinates.positionInWindow()}" + + " bounds=${coordinates.boundsInWindow()}" + } + val boundsInWindow = coordinates.boundsInWindow() + viewModel.setPlaceholderPositionInWindow( + top = boundsInWindow.top, + bottom = boundsInWindow.bottom, + ) + } ) { - Text( - text = "Notifications", - modifier = Modifier.align(Alignment.CenterHorizontally), - style = MaterialTheme.typography.titleLarge, - color = MaterialTheme.colorScheme.onSurface, - ) - Spacer(modifier = Modifier.weight(1f)) - Text( - text = "Shelf", - modifier = Modifier.align(Alignment.CenterHorizontally), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.onSurface, - ) + val animatedExpansion by + animateSharedFloatAsState( + value = if (form == Form.HunFromTop) 0f else 1f, + key = SharedExpansionValue, + element = key + ) + debugLog(viewModel) { "STACK composed: expansion=$animatedExpansion" } + if (viewModel.isPlaceholderTextVisible) { + Text( + text = "Notifications", + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.align(Alignment.Center), + ) + } + } +} + +private inline fun debugLog( + viewModel: NotificationsPlaceholderViewModel, + msg: () -> Any, +) { + if (viewModel.isDebugLoggingEnabled) { + Log.d(TAG, msg().toString()) } } + +private fun Modifier.debugBackground( + viewModel: NotificationsPlaceholderViewModel, + color: Color = DEBUG_COLOR, +): Modifier = + if (viewModel.isVisualDebuggingEnabled) { + background(color) + } else { + this + } + +private const val TAG = "FlexiNotifs" +private val DEBUG_COLOR = Color(1f, 0f, 0f, 0.2f) 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 b9451d1c1585..9dd7bfaf3549 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 @@ -24,6 +24,7 @@ import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight @@ -43,6 +44,7 @@ import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel import com.android.systemui.scene.shared.model.SceneKey @@ -101,53 +103,59 @@ private fun SceneScope.QuickSettingsScene( modifier: Modifier = Modifier, ) { // TODO(b/280887232): implement the real UI. - val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() - val collapsedHeaderHeight = - with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = - modifier - .fillMaxSize() - .clickable(onClick = { viewModel.onContentClicked() }) - .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) - ) { - when (LocalWindowSizeClass.current.widthSizeClass) { - WindowWidthSizeClass.Compact -> - AnimatedVisibility( - visible = !isCustomizing, - enter = - expandVertically( - animationSpec = tween(1000), - initialHeight = { collapsedHeaderHeight }, - ) + fadeIn(tween(1000)), - exit = - shrinkVertically( - animationSpec = tween(1000), - targetHeight = { collapsedHeaderHeight }, - shrinkTowards = Alignment.Top, - ) + fadeOut(tween(1000)), - ) { - ExpandedShadeHeader( + Box(modifier = modifier.fillMaxSize()) { + val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() + val collapsedHeaderHeight = + with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = + Modifier.fillMaxSize() + .clickable(onClick = { viewModel.onContentClicked() }) + .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) + ) { + when (LocalWindowSizeClass.current.widthSizeClass) { + WindowWidthSizeClass.Compact -> + AnimatedVisibility( + visible = !isCustomizing, + enter = + expandVertically( + animationSpec = tween(1000), + initialHeight = { collapsedHeaderHeight }, + ) + fadeIn(tween(1000)), + exit = + shrinkVertically( + animationSpec = tween(1000), + targetHeight = { collapsedHeaderHeight }, + shrinkTowards = Alignment.Top, + ) + fadeOut(tween(1000)), + ) { + ExpandedShadeHeader( + viewModel = viewModel.shadeHeaderViewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + ) + } + else -> + CollapsedShadeHeader( viewModel = viewModel.shadeHeaderViewModel, createTintedIconManager = createTintedIconManager, createBatteryMeterViewController = createBatteryMeterViewController, statusBarIconController = statusBarIconController, ) - } - else -> - CollapsedShadeHeader( - viewModel = viewModel.shadeHeaderViewModel, - createTintedIconManager = createTintedIconManager, - createBatteryMeterViewController = createBatteryMeterViewController, - statusBarIconController = statusBarIconController, - ) + } + Spacer(modifier = Modifier.height(16.dp)) + QuickSettings( + modifier = Modifier.fillMaxHeight(), + viewModel.qsSceneAdapter, + QSSceneAdapter.State.QS + ) } - Spacer(modifier = Modifier.height(16.dp)) - QuickSettings( - modifier = Modifier.fillMaxHeight(), - viewModel.qsSceneAdapter, - QSSceneAdapter.State.QS + HeadsUpNotificationSpace( + viewModel = viewModel.notifications, + isPeekFromBottom = true, + modifier = Modifier.padding(16.dp).fillMaxSize(), ) } } 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 f35ea8373db7..bded98d52481 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 @@ -17,15 +17,20 @@ package com.android.systemui.scene.ui.composable import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Edge import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.UserAction +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -36,7 +41,11 @@ import kotlinx.coroutines.flow.asStateFlow * content from the scene framework. */ @SysUISingleton -class GoneScene @Inject constructor() : ComposableScene { +class GoneScene +@Inject +constructor( + private val notificationsViewModel: NotificationsPlaceholderViewModel, +) : ComposableScene { override val key = SceneKey.Gone override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> = @@ -56,6 +65,11 @@ class GoneScene @Inject constructor() : ComposableScene { override fun SceneScope.Content( modifier: Modifier, ) { - Box(modifier = modifier) + Box(modifier = modifier) { + HeadsUpNotificationSpace( + viewModel = notificationsViewModel, + modifier = Modifier.padding(16.dp).fillMaxSize(), + ) + } } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt index 45df2b1bb20c..6bb525aa00fb 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToShadeTransition.kt @@ -3,10 +3,12 @@ package com.android.systemui.scene.ui.composable.transitions import androidx.compose.animation.core.tween import com.android.compose.animation.scene.Edge import com.android.compose.animation.scene.TransitionBuilder +import com.android.systemui.notifications.ui.composable.Notifications import com.android.systemui.scene.ui.composable.Shade fun TransitionBuilder.goneToShadeTransition() { spec = tween(durationMillis = 500) translate(Shade.rootElementKey, Edge.Top, true) + fade(Notifications.Elements.NotificationScrim) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToShadeTransition.kt index fadbdce80cbf..ebc343dc6d76 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToShadeTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToShadeTransition.kt @@ -10,7 +10,6 @@ import com.android.systemui.shade.ui.composable.Shade fun TransitionBuilder.lockscreenToShadeTransition() { spec = tween(durationMillis = 500) - punchHole(Shade.Elements.QuickSettings, bounds = Shade.Elements.Scrim, Shade.Shapes.Scrim) translate(Shade.Elements.Scrim, Edge.Top, startsOutsideLayoutBounds = false) fractionRange(end = 0.5f) { fade(Shade.Elements.ScrimBackground) @@ -20,5 +19,5 @@ fun TransitionBuilder.lockscreenToShadeTransition() { startsOutsideLayoutBounds = false, ) } - fractionRange(start = 0.5f) { fade(Notifications.Elements.Notifications) } + fractionRange(start = 0.5f) { fade(Notifications.Elements.NotificationScrim) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromShadeToQuickSettingsTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromShadeToQuickSettingsTransition.kt index 5616175ed11c..d5c2a03b3f9f 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromShadeToQuickSettingsTransition.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromShadeToQuickSettingsTransition.kt @@ -10,7 +10,7 @@ import com.android.systemui.shade.ui.composable.ShadeHeader fun TransitionBuilder.shadeToQuickSettingsTransition() { spec = tween(durationMillis = 500) - translate(Notifications.Elements.Notifications, Edge.Bottom) + translate(Notifications.Elements.NotificationScrim, Edge.Bottom) timestampRange(endMillis = 83) { fade(QuickSettings.Elements.FooterActions) } translate(ShadeHeader.Elements.CollapsedContent, y = ShadeHeader.Dimensions.CollapsedHeight) 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 a02f046a18f5..2df151bc2d8e 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 @@ -37,7 +37,7 @@ import com.android.compose.animation.scene.SceneScope import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.notifications.ui.composable.Notifications +import com.android.systemui.notifications.ui.composable.NotificationStack import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.composable.QuickSettings import com.android.systemui.scene.shared.model.Direction @@ -160,7 +160,11 @@ private fun SceneScope.ShadeScene( QSSceneAdapter.State.QQS ) Spacer(modifier = Modifier.height(16.dp)) - Notifications(modifier = Modifier.weight(1f)) + NotificationStack( + viewModel = viewModel.notifications, + isScrimVisible = true, + modifier = Modifier.weight(1f), + ) } } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt index 3b999e304491..2b1195229c76 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt @@ -17,6 +17,7 @@ package com.android.compose.animation.scene import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.movableContentOf import androidx.compose.runtime.mutableStateOf @@ -25,16 +26,17 @@ import androidx.compose.runtime.snapshots.Snapshot import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.isSpecified import androidx.compose.ui.geometry.isUnspecified import androidx.compose.ui.geometry.lerp +import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.graphics.drawscope.scale import androidx.compose.ui.layout.IntermediateMeasureScope import androidx.compose.ui.layout.Measurable import androidx.compose.ui.layout.Placeable import androidx.compose.ui.layout.intermediateLayout +import androidx.compose.ui.node.DrawModifierNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.Constraints @@ -46,6 +48,7 @@ import com.android.compose.ui.util.lerp import kotlinx.coroutines.launch /** An element on screen, that can be composed in one or more scenes. */ +@Stable internal class Element(val key: ElementKey) { /** * The last values of this element, coming from any scene. Note that this value will be unstable @@ -90,6 +93,7 @@ internal class Element(val key: ElementKey) { } /** The target values of this element in a given scene. */ + @Stable class TargetValues(val scene: SceneKey) { val lastValues = Values() @@ -107,6 +111,7 @@ internal class Element(val key: ElementKey) { } /** A shared value of this element. */ + @Stable class SharedValue<T>(val key: ValueKey, initialValue: T) { var value by mutableStateOf(initialValue) } @@ -126,6 +131,7 @@ data class Scale(val scaleX: Float, val scaleY: Float, val pivot: Offset = Offse /** The implementation of [SceneScope.element]. */ @OptIn(ExperimentalComposeUiApi::class) +@Stable internal fun Modifier.element( layoutImpl: SceneTransitionLayoutImpl, scene: Scene, @@ -144,24 +150,9 @@ internal fun Modifier.element( ?: Element.TargetValues(scene.key).also { element.sceneValues[scene.key] = it } } - return this.then(ElementModifier(layoutImpl, element, sceneValues)) - .drawWithContent { - if (shouldDrawElement(layoutImpl, scene, element)) { - val drawScale = getDrawScale(layoutImpl, element, scene, sceneValues) - if (drawScale == Scale.Default) { - drawContent() - } else { - scale( - drawScale.scaleX, - drawScale.scaleY, - if (drawScale.pivot.isUnspecified) center else drawScale.pivot, - ) { - this@drawWithContent.drawContent() - } - } - } - } - .modifierTransformations(layoutImpl, scene, element, sceneValues) + return this.then(ElementModifier(layoutImpl, scene, element, sceneValues)) + // TODO(b/311132415): Move this into ElementNode once we can create a delegate + // IntermediateLayoutModifierNode. .intermediateLayout { measurable, constraints -> val placeable = measure(layoutImpl, scene, element, sceneValues, measurable, constraints) @@ -178,22 +169,25 @@ internal fun Modifier.element( */ private data class ElementModifier( private val layoutImpl: SceneTransitionLayoutImpl, + private val scene: Scene, private val element: Element, private val sceneValues: Element.TargetValues, ) : ModifierNodeElement<ElementNode>() { - override fun create(): ElementNode = ElementNode(layoutImpl, element, sceneValues) + override fun create(): ElementNode = ElementNode(layoutImpl, scene, element, sceneValues) override fun update(node: ElementNode) { - node.update(layoutImpl, element, sceneValues) + node.update(layoutImpl, scene, element, sceneValues) } } internal class ElementNode( layoutImpl: SceneTransitionLayoutImpl, + scene: Scene, element: Element, sceneValues: Element.TargetValues, -) : Modifier.Node() { +) : Modifier.Node(), DrawModifierNode { private var layoutImpl: SceneTransitionLayoutImpl = layoutImpl + private var scene: Scene = scene private var element: Element = element private var sceneValues: Element.TargetValues = sceneValues @@ -239,15 +233,34 @@ internal class ElementNode( fun update( layoutImpl: SceneTransitionLayoutImpl, + scene: Scene, element: Element, sceneValues: Element.TargetValues, ) { removeNodeFromSceneValues() this.layoutImpl = layoutImpl + this.scene = scene this.element = element this.sceneValues = sceneValues addNodeToSceneValues() } + + override fun ContentDrawScope.draw() { + if (shouldDrawElement(layoutImpl, scene, element)) { + val drawScale = getDrawScale(layoutImpl, element, scene, sceneValues) + if (drawScale == Scale.Default) { + drawContent() + } else { + scale( + drawScale.scaleX, + drawScale.scaleY, + if (drawScale.pivot.isUnspecified) center else drawScale.pivot, + ) { + this@draw.drawContent() + } + } + } + } } private fun shouldDrawElement( @@ -332,39 +345,6 @@ internal fun sharedElementTransformation( } /** - * Chain the [com.android.compose.animation.scene.transformation.ModifierTransformation] applied - * throughout the current transition, if any. - */ -private fun Modifier.modifierTransformations( - layoutImpl: SceneTransitionLayoutImpl, - scene: Scene, - element: Element, - sceneValues: Element.TargetValues, -): Modifier { - when (val state = layoutImpl.state.transitionState) { - is TransitionState.Idle -> return this - is TransitionState.Transition -> { - val fromScene = state.fromScene - val toScene = state.toScene - if (fromScene == toScene) { - // Same as idle. - return this - } - - return layoutImpl.transitions - .transitionSpec(fromScene, state.toScene) - .transformations(element.key, scene.key) - .modifier - .fold(this) { modifier, transformation -> - with(transformation) { - modifier.transform(layoutImpl, scene, element, sceneValues) - } - } - } - } -} - -/** * Whether the element is opaque or not. * * Important: The logic here should closely match the logic in [elementAlpha]. Note that we don't diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt index 5b752eb4e900..84d3b8647d6c 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Key.kt @@ -17,11 +17,13 @@ package com.android.compose.animation.scene import androidx.annotation.VisibleForTesting +import androidx.compose.runtime.Stable /** * A base class to create unique keys, associated to an [identity] that is used to check the * equality of two key instances. */ +@Stable sealed class Key(val debugName: String, val identity: Any) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt index d48781a4529b..a0fba8076517 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt @@ -23,20 +23,25 @@ import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellati import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation import androidx.compose.foundation.gestures.horizontalDrag import androidx.compose.foundation.gestures.verticalDrag +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier -import androidx.compose.ui.composed import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.pointer.PointerEvent import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.PointerId import androidx.compose.ui.input.pointer.PointerInputChange import androidx.compose.ui.input.pointer.PointerInputScope +import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.positionChange import androidx.compose.ui.input.pointer.util.VelocityTracker import androidx.compose.ui.input.pointer.util.addPointerInputChange +import androidx.compose.ui.node.CompositionLocalConsumerModifierNode +import androidx.compose.ui.node.DelegatingNode +import androidx.compose.ui.node.ModifierNodeElement +import androidx.compose.ui.node.PointerInputModifierNode +import androidx.compose.ui.node.currentValueOf import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.Velocity @@ -56,7 +61,7 @@ import androidx.compose.ui.util.fastForEach * dragged) and a second pointer is down and dragged. This is an implementation detail that might * change in the future. */ -// TODO(b/291055080): Migrate to the Modifier.Node API. +@Stable internal fun Modifier.multiPointerDraggable( orientation: Orientation, enabled: Boolean, @@ -64,22 +69,88 @@ internal fun Modifier.multiPointerDraggable( onDragStarted: (layoutSize: IntSize, startedPosition: Offset, pointersDown: Int) -> Unit, onDragDelta: (Float) -> Unit, onDragStopped: (velocity: Float) -> Unit, -): Modifier = composed { - val onDragStarted by rememberUpdatedState(onDragStarted) - val onDragStopped by rememberUpdatedState(onDragStopped) - val onDragDelta by rememberUpdatedState(onDragDelta) - val startDragImmediately by rememberUpdatedState(startDragImmediately) - - val velocityTracker = remember { VelocityTracker() } - val maxFlingVelocity = - LocalViewConfiguration.current.maximumFlingVelocity.let { max -> - val maxF = max.toFloat() - Velocity(maxF, maxF) +): Modifier = + this.then( + MultiPointerDraggableElement( + orientation, + enabled, + startDragImmediately, + onDragStarted, + onDragDelta, + onDragStopped, + ) + ) + +private data class MultiPointerDraggableElement( + private val orientation: Orientation, + private val enabled: Boolean, + private val startDragImmediately: Boolean, + private val onDragStarted: + (layoutSize: IntSize, startedPosition: Offset, pointersDown: Int) -> Unit, + private val onDragDelta: (Float) -> Unit, + private val onDragStopped: (velocity: Float) -> Unit, +) : ModifierNodeElement<MultiPointerDraggableNode>() { + override fun create(): MultiPointerDraggableNode = + MultiPointerDraggableNode( + orientation = orientation, + enabled = enabled, + startDragImmediately = startDragImmediately, + onDragStarted = onDragStarted, + onDragDelta = onDragDelta, + onDragStopped = onDragStopped, + ) + + override fun update(node: MultiPointerDraggableNode) { + node.orientation = orientation + node.enabled = enabled + node.startDragImmediately = startDragImmediately + node.onDragStarted = onDragStarted + node.onDragDelta = onDragDelta + node.onDragStopped = onDragStopped + } +} + +private class MultiPointerDraggableNode( + orientation: Orientation, + enabled: Boolean, + var startDragImmediately: Boolean, + var onDragStarted: (layoutSize: IntSize, startedPosition: Offset, pointersDown: Int) -> Unit, + var onDragDelta: (Float) -> Unit, + var onDragStopped: (velocity: Float) -> Unit, +) : PointerInputModifierNode, DelegatingNode(), CompositionLocalConsumerModifierNode { + private val pointerInputHandler: suspend PointerInputScope.() -> Unit = { pointerInput() } + private val delegate = delegate(SuspendingPointerInputModifierNode(pointerInputHandler)) + private val velocityTracker = VelocityTracker() + + var enabled: Boolean = enabled + set(value) { + // Reset the pointer input whenever enabled changed. + if (value != field) { + field = value + delegate.resetPointerInputHandler() + } + } + + var orientation: Orientation = orientation + set(value) { + // Reset the pointer input whenever enabled orientation. + if (value != field) { + field = value + delegate.resetPointerInputHandler() + } } - pointerInput(enabled, orientation, maxFlingVelocity) { + override fun onCancelPointerInput() = delegate.onCancelPointerInput() + + override fun onPointerEvent( + pointerEvent: PointerEvent, + pass: PointerEventPass, + bounds: IntSize + ) = delegate.onPointerEvent(pointerEvent, pass, bounds) + + private suspend fun PointerInputScope.pointerInput() { if (!enabled) { - return@pointerInput + return } val onDragStart: (Offset, Int) -> Unit = { startedPosition, pointersDown -> @@ -90,6 +161,12 @@ internal fun Modifier.multiPointerDraggable( val onDragCancel: () -> Unit = { onDragStopped(/* velocity= */ 0f) } val onDragEnd: () -> Unit = { + val maxFlingVelocity = + currentValueOf(LocalViewConfiguration).maximumFlingVelocity.let { max -> + val maxF = max.toFloat() + Velocity(maxF, maxF) + } + val velocity = velocityTracker.calculateVelocity(maxFlingVelocity) onDragStopped( when (orientation) { diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/PunchHole.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt index 984086b7792a..560e92becba5 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/PunchHole.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PunchHole.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ * limitations under the License. */ -package com.android.compose.animation.scene.transformation +package com.android.compose.animation.scene import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.toRect @@ -28,52 +27,68 @@ import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawOutline +import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.drawscope.translate import androidx.compose.ui.graphics.withSaveLayer +import androidx.compose.ui.node.DrawModifierNode +import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.unit.toSize -import com.android.compose.animation.scene.Element -import com.android.compose.animation.scene.ElementKey -import com.android.compose.animation.scene.ElementMatcher -import com.android.compose.animation.scene.Scene -import com.android.compose.animation.scene.SceneTransitionLayoutImpl -/** Punch a hole in an element using the bounds of another element and a given [shape]. */ -internal class PunchHole( - override val matcher: ElementMatcher, +internal fun Modifier.punchHole( + layoutImpl: SceneTransitionLayoutImpl, + element: ElementKey, + bounds: ElementKey, + shape: Shape, +): Modifier = this.then(PunchHoleElement(layoutImpl, element, bounds, shape)) + +private data class PunchHoleElement( + private val layoutImpl: SceneTransitionLayoutImpl, + private val element: ElementKey, private val bounds: ElementKey, private val shape: Shape, -) : ModifierTransformation { +) : ModifierNodeElement<PunchHoleNode>() { + override fun create(): PunchHoleNode = PunchHoleNode(layoutImpl, element, bounds, shape) + override fun update(node: PunchHoleNode) { + node.layoutImpl = layoutImpl + node.element = element + node.bounds = bounds + node.shape = shape + } +} + +private class PunchHoleNode( + var layoutImpl: SceneTransitionLayoutImpl, + var element: ElementKey, + var bounds: ElementKey, + var shape: Shape, +) : Modifier.Node(), DrawModifierNode { private var lastSize: Size = Size.Unspecified private var lastLayoutDirection: LayoutDirection = LayoutDirection.Ltr private var lastOutline: Outline? = null - override fun Modifier.transform( - layoutImpl: SceneTransitionLayoutImpl, - scene: Scene, - element: Element, - sceneValues: Element.TargetValues, - ): Modifier { - return drawWithContent { - val bounds = layoutImpl.elements[bounds] - if ( - bounds == null || - bounds.lastSharedValues.size == Element.SizeUnspecified || - bounds.lastSharedValues.offset == Offset.Unspecified - ) { + override fun ContentDrawScope.draw() { + val bounds = layoutImpl.elements[bounds] + + if ( + bounds == null || + bounds.lastSharedValues.size == Element.SizeUnspecified || + bounds.lastSharedValues.offset == Offset.Unspecified + ) { + drawContent() + return + } + + val element = layoutImpl.elements.getValue(element) + drawIntoCanvas { canvas -> + canvas.withSaveLayer(size.toRect(), Paint()) { drawContent() - return@drawWithContent - } - drawIntoCanvas { canvas -> - canvas.withSaveLayer(size.toRect(), Paint()) { - drawContent() - val offset = bounds.lastSharedValues.offset - element.lastSharedValues.offset - translate(offset.x, offset.y) { drawHole(bounds) } - } + val offset = bounds.lastSharedValues.offset - element.lastSharedValues.offset + translate(offset.x, offset.y) { drawHole(bounds) } } } } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt index 857a596a1404..f5561cb404b6 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt @@ -19,20 +19,24 @@ package com.android.compose.animation.scene import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshots.Snapshot import androidx.compose.runtime.snapshots.SnapshotStateMap import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.intermediateLayout import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.IntSize import androidx.compose.ui.zIndex /** A scene in a [SceneTransitionLayout]. */ +@Stable internal class Scene( val key: SceneKey, layoutImpl: SceneTransitionLayoutImpl, @@ -104,11 +108,13 @@ private class SceneScopeImpl( ): State<T> { val element = element?.let { key -> - layoutImpl.elements[key] - ?: error( - "Element $key is not composed. Make sure to call animateSharedXAsState " + - "*after* Modifier.element(key)." - ) + Snapshot.withoutReadObservation { + layoutImpl.elements[key] + ?: error( + "Element $key is not composed. Make sure to call " + + "animateSharedXAsState *after* Modifier.element(key)." + ) + } } return animateSharedValueAsState( @@ -130,4 +136,10 @@ private class SceneScopeImpl( ) { MovableElement(layoutImpl, scene, key, modifier, content) } + + override fun Modifier.punchHole( + element: ElementKey, + bounds: ElementKey, + shape: Shape + ): Modifier = punchHole(layoutImpl, element, bounds, shape) } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneGestureHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneGestureHandler.kt index c51287a7bb71..b00c88612269 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneGestureHandler.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneGestureHandler.kt @@ -27,7 +27,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.IntSize -import androidx.compose.ui.unit.Velocity import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.round import com.android.compose.nestedscroll.PriorityNestedScrollConnection @@ -536,24 +535,6 @@ internal class SceneNestedScrollHandler( ) : NestedScrollHandler { override val connection: PriorityNestedScrollConnection = nestedScrollConnection() - private fun Offset.toAmount() = - when (gestureHandler.orientation) { - Orientation.Horizontal -> x - Orientation.Vertical -> y - } - - private fun Velocity.toAmount() = - when (gestureHandler.orientation) { - Orientation.Horizontal -> x - Orientation.Vertical -> y - } - - private fun Float.toOffset() = - when (gestureHandler.orientation) { - Orientation.Horizontal -> Offset(x = this, y = 0f) - Orientation.Vertical -> Offset(x = 0f, y = this) - } - private fun nestedScrollConnection(): PriorityNestedScrollConnection { // If we performed a long gesture before entering priority mode, we would have to avoid // moving on to the next scene. @@ -591,13 +572,12 @@ internal class SceneNestedScrollHandler( } return PriorityNestedScrollConnection( + orientation = gestureHandler.orientation, canStartPreScroll = { offsetAvailable, offsetBeforeStart -> - canChangeScene = offsetBeforeStart == Offset.Zero + canChangeScene = offsetBeforeStart == 0f val canInterceptSwipeTransition = - canChangeScene && - gestureHandler.isDrivingTransition && - offsetAvailable.toAmount() != 0f + canChangeScene && gestureHandler.isDrivingTransition && offsetAvailable != 0f if (!canInterceptSwipeTransition) return@PriorityNestedScrollConnection false val progress = gestureHandler.swipeTransition.progress @@ -618,15 +598,14 @@ internal class SceneNestedScrollHandler( !shouldSnapToIdle }, canStartPostScroll = { offsetAvailable, offsetBeforeStart -> - val amount = offsetAvailable.toAmount() val behavior: NestedScrollBehavior = when { - amount > 0 -> startBehavior - amount < 0 -> endBehavior + offsetAvailable > 0f -> startBehavior + offsetAvailable < 0f -> endBehavior else -> return@PriorityNestedScrollConnection false } - val isZeroOffset = offsetBeforeStart == Offset.Zero + val isZeroOffset = offsetBeforeStart == 0f when (behavior) { NestedScrollBehavior.DuringTransitionBetweenScenes -> { @@ -635,30 +614,29 @@ internal class SceneNestedScrollHandler( } NestedScrollBehavior.EdgeNoOverscroll -> { canChangeScene = isZeroOffset - isZeroOffset && hasNextScene(amount) + isZeroOffset && hasNextScene(offsetAvailable) } NestedScrollBehavior.EdgeWithOverscroll -> { canChangeScene = isZeroOffset - hasNextScene(amount) + hasNextScene(offsetAvailable) } NestedScrollBehavior.Always -> { canChangeScene = true - hasNextScene(amount) + hasNextScene(offsetAvailable) } } }, canStartPostFling = { velocityAvailable -> - val amount = velocityAvailable.toAmount() val behavior: NestedScrollBehavior = when { - amount > 0 -> startBehavior - amount < 0 -> endBehavior + velocityAvailable > 0f -> startBehavior + velocityAvailable < 0f -> endBehavior else -> return@PriorityNestedScrollConnection false } // We could start an overscroll animation canChangeScene = false - behavior.canStartOnPostFling && hasNextScene(amount) + behavior.canStartOnPostFling && hasNextScene(velocityAvailable) }, canContinueScroll = { true }, onStart = { @@ -671,24 +649,22 @@ internal class SceneNestedScrollHandler( }, onScroll = { offsetAvailable -> if (gestureHandler.gestureWithPriority != this) { - return@PriorityNestedScrollConnection Offset.Zero + return@PriorityNestedScrollConnection 0f } - val amount = offsetAvailable.toAmount() - // TODO(b/297842071) We should handle the overscroll or slow drag if the gesture is // initiated in a nested child. - gestureHandler.onDrag(amount) + gestureHandler.onDrag(offsetAvailable) - amount.toOffset() + offsetAvailable }, onStop = { velocityAvailable -> if (gestureHandler.gestureWithPriority != this) { - return@PriorityNestedScrollConnection Velocity.Zero + return@PriorityNestedScrollConnection 0f } gestureHandler.onDragStopped( - velocity = velocityAvailable.toAmount(), + velocity = velocityAvailable, canChangeScene = canChangeScene ) 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 30d13dfa3f70..07add77eccd4 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 @@ -19,10 +19,12 @@ package com.android.compose.animation.scene import androidx.annotation.FloatRange import androidx.compose.foundation.gestures.Orientation import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.runtime.State import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.platform.LocalDensity @@ -94,6 +96,7 @@ interface SceneTransitionLayoutScope { @DslMarker annotation class ElementDsl @ElementDsl +@Stable interface SceneScope { /** The state of the [SceneTransitionLayout] in which this scene is contained. */ val layoutState: SceneTransitionLayoutState @@ -177,6 +180,18 @@ interface SceneScope { lerp: (start: T, stop: T, fraction: Float) -> T, canOverflow: Boolean, ): State<T> + + /** + * Punch a hole in this [element] using the bounds of [bounds] in [scene] and the given [shape]. + * + * Punching a hole in an element will "remove" any pixel drawn by that element in the hole area. + * This can be used to make content drawn below an opaque element visible. For example, if we + * have [this lockscreen scene](http://shortn/_VYySFnJDhN) drawn below + * [this shade scene](http://shortn/_fpxGUk0Rg7) and punch a hole in the latter using the big + * clock time bounds and a RoundedCornerShape(10dp), [this](http://shortn/_qt80IvORFj) would be + * the result. + */ + fun Modifier.punchHole(element: ElementKey, bounds: ElementKey, shape: Shape): Modifier } // TODO(b/291053742): Add animateSharedValueAsState(targetValue) without any ValueKey and ElementKey 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 60f385aede02..02ddccbc051b 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 @@ -23,6 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateOf @@ -41,6 +42,7 @@ import com.android.compose.ui.util.lerp import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel +@Stable internal class SceneTransitionLayoutImpl( onChangeScene: (SceneKey) -> Unit, builder: SceneTransitionLayoutScope.() -> Unit, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt index 64c9775a386e..f48e9147eef4 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt @@ -16,11 +16,13 @@ package com.android.compose.animation.scene +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue /** The state of a [SceneTransitionLayout]. */ +@Stable class SceneTransitionLayoutState(initialScene: SceneKey) { /** * The current [TransitionState]. All values read here are backed by the Snapshot system. @@ -29,7 +31,6 @@ class SceneTransitionLayoutState(initialScene: SceneKey) { * [SceneTransitionLayoutState.observableTransitionState] instead. */ var transitionState: TransitionState by mutableStateOf(TransitionState.Idle(initialScene)) - internal set /** * Whether we are transitioning, optionally restricting the check to the transition between @@ -46,8 +47,15 @@ class SceneTransitionLayoutState(initialScene: SceneKey) { return (from == null || transition.fromScene == from) && (to == null || transition.toScene == to) } + + /** Whether we are transitioning from [scene] to [other], or from [other] to [scene]. */ + fun isTransitioningBetween(scene: SceneKey, other: SceneKey): Boolean { + return isTransitioning(from = scene, to = other) || + isTransitioning(from = other, to = scene) + } } +@Stable sealed interface TransitionState { /** * The current effective scene. If a new transition was triggered, it would start from this diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt index 2172ed300a33..f91895bb0e05 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt @@ -18,6 +18,7 @@ package com.android.compose.animation.scene import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.snap +import androidx.compose.runtime.Stable import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.util.fastForEach @@ -27,7 +28,6 @@ import com.android.compose.animation.scene.transformation.AnchoredTranslate import com.android.compose.animation.scene.transformation.DrawScale import com.android.compose.animation.scene.transformation.EdgeTranslate import com.android.compose.animation.scene.transformation.Fade -import com.android.compose.animation.scene.transformation.ModifierTransformation import com.android.compose.animation.scene.transformation.PropertyTransformation import com.android.compose.animation.scene.transformation.RangedPropertyTransformation import com.android.compose.animation.scene.transformation.ScaleSize @@ -93,6 +93,7 @@ class SceneTransitions( } /** The definition of a transition between [from] and [to]. */ +@Stable data class TransitionSpec( val from: SceneKey?, val to: SceneKey?, @@ -122,7 +123,6 @@ data class TransitionSpec( scene: SceneKey, ): ElementTransformations { var shared: SharedElementTransformation? = null - val modifier = mutableListOf<ModifierTransformation>() var offset: PropertyTransformation<Offset>? = null var size: PropertyTransformation<IntSize>? = null var drawScale: PropertyTransformation<Scale>? = null @@ -166,12 +166,11 @@ data class TransitionSpec( throwIfNotNull(shared, element, name = "shared") shared = transformation } - is ModifierTransformation -> modifier.add(transformation) is PropertyTransformation<*> -> onPropertyTransformation(transformation) } } - return ElementTransformations(shared, modifier, offset, size, drawScale, alpha) + return ElementTransformations(shared, offset, size, drawScale, alpha) } private fun throwIfNotNull( @@ -188,7 +187,6 @@ data class TransitionSpec( /** The transformations of an element during a transition. */ internal class ElementTransformations( val shared: SharedElementTransformation?, - val modifier: List<ModifierTransformation>, val offset: PropertyTransformation<Offset>?, val size: PropertyTransformation<IntSize>?, val drawScale: PropertyTransformation<Scale>?, diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt index ca66dff5e231..f820074ec3d1 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt @@ -18,8 +18,6 @@ package com.android.compose.animation.scene import androidx.compose.animation.core.AnimationSpec import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -131,19 +129,6 @@ interface TransitionBuilder : PropertyTransformationBuilder { ) /** - * Punch a hole in the element(s) matching [matcher] that has the same bounds as [bounds] and - * using the given [shape]. - * - * Punching a hole in an element will "remove" any pixel drawn by that element in the hole area. - * This can be used to make content drawn below an opaque element visible. For example, if we - * have [this lockscreen scene](http://shortn/_VYySFnJDhN) drawn below - * [this shade scene](http://shortn/_fpxGUk0Rg7) and punch a hole in the latter using the big - * clock time bounds and a RoundedCornerShape(10dp), [this](http://shortn/_qt80IvORFj) would be - * the result. - */ - fun punchHole(matcher: ElementMatcher, bounds: ElementKey, shape: Shape = RectangleShape) - - /** * Adds the transformations in [builder] but in reversed order. This allows you to partially * reuse the definition of the transition from scene `Foo` to scene `Bar` inside the definition * of the transition from scene `Bar` to scene `Foo`. diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt index d4909892f492..8c0a5a394331 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt @@ -22,7 +22,6 @@ import androidx.compose.animation.core.Spring import androidx.compose.animation.core.VectorConverter import androidx.compose.animation.core.spring import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp import com.android.compose.animation.scene.transformation.AnchoredSize import com.android.compose.animation.scene.transformation.AnchoredTranslate @@ -30,7 +29,6 @@ import com.android.compose.animation.scene.transformation.DrawScale import com.android.compose.animation.scene.transformation.EdgeTranslate import com.android.compose.animation.scene.transformation.Fade import com.android.compose.animation.scene.transformation.PropertyTransformation -import com.android.compose.animation.scene.transformation.PunchHole import com.android.compose.animation.scene.transformation.RangedPropertyTransformation import com.android.compose.animation.scene.transformation.ScaleSize import com.android.compose.animation.scene.transformation.SharedElementTransformation @@ -93,10 +91,6 @@ internal class TransitionBuilderImpl : TransitionBuilder { spec.vectorize(Float.VectorConverter).durationMillis } - override fun punchHole(matcher: ElementMatcher, bounds: ElementKey, shape: Shape) { - transformations.add(PunchHole(matcher, bounds, shape)) - } - override fun reversed(builder: TransitionBuilder.() -> Unit) { reversed = true builder() diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt index 0db8469466ef..206935558179 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transformation/Transformation.kt @@ -16,7 +16,6 @@ package com.android.compose.animation.scene.transformation -import androidx.compose.ui.Modifier import com.android.compose.animation.scene.Element import com.android.compose.animation.scene.ElementMatcher import com.android.compose.animation.scene.Scene @@ -52,19 +51,6 @@ internal class SharedElementTransformation( internal val scenePicker: SharedElementScenePicker, ) : Transformation -/** A transformation that is applied on the element during the whole transition. */ -internal interface ModifierTransformation : Transformation { - /** Apply the transformation to [element]. */ - // TODO(b/290184746): Figure out a public API for custom transformations that don't have access - // to these internal classes. - fun Modifier.transform( - layoutImpl: SceneTransitionLayoutImpl, - scene: Scene, - element: Element, - sceneValues: Element.TargetValues, - ): Modifier -} - /** A transformation that changes the value of an element property, like its size or offset. */ internal sealed interface PropertyTransformation<T> : Transformation { /** diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt index 824c10b88a9b..a5fd1bfb72e6 100644 --- a/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt +++ b/packages/SystemUI/compose/scene/src/com/android/compose/nestedscroll/PriorityNestedScrollConnection.kt @@ -16,10 +16,12 @@ package com.android.compose.nestedscroll +import androidx.compose.foundation.gestures.Orientation import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.unit.Velocity +import com.android.compose.ui.util.SpaceVectorConverter /** * This [NestedScrollConnection] waits for a child to scroll ([onPreScroll] or [onPostScroll]), and @@ -147,3 +149,35 @@ class PriorityNestedScrollConnection( return onStop(velocity) } } + +fun PriorityNestedScrollConnection( + orientation: Orientation, + canStartPreScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, + canStartPostScroll: (offsetAvailable: Float, offsetBeforeStart: Float) -> Boolean, + canStartPostFling: (velocityAvailable: Float) -> Boolean, + canContinueScroll: () -> Boolean, + onStart: () -> Unit, + onScroll: (offsetAvailable: Float) -> Float, + onStop: (velocityAvailable: Float) -> Float, +) = + with(SpaceVectorConverter(orientation)) { + PriorityNestedScrollConnection( + canStartPreScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> + canStartPreScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) + }, + canStartPostScroll = { offsetAvailable: Offset, offsetBeforeStart: Offset -> + canStartPostScroll(offsetAvailable.toFloat(), offsetBeforeStart.toFloat()) + }, + canStartPostFling = { velocityAvailable: Velocity -> + canStartPostFling(velocityAvailable.toFloat()) + }, + canContinueScroll = canContinueScroll, + onStart = onStart, + onScroll = { offsetAvailable: Offset -> + onScroll(offsetAvailable.toFloat()).toOffset() + }, + onStop = { velocityAvailable: Velocity -> + onStop(velocityAvailable.toFloat()).toVelocity() + }, + ) + } diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/SpaceVectorConverter.kt b/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/SpaceVectorConverter.kt new file mode 100644 index 000000000000..a13e9441523a --- /dev/null +++ b/packages/SystemUI/compose/scene/src/com/android/compose/ui/util/SpaceVectorConverter.kt @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.compose.ui.util + +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.unit.Velocity + +interface SpaceVectorConverter { + fun Offset.toFloat(): Float + fun Velocity.toFloat(): Float + fun Float.toOffset(): Offset + fun Float.toVelocity(): Velocity +} + +fun SpaceVectorConverter(orientation: Orientation) = + when (orientation) { + Orientation.Horizontal -> HorizontalConverter + Orientation.Vertical -> VerticalConverter + } + +private val HorizontalConverter = + object : SpaceVectorConverter { + override fun Offset.toFloat() = x + override fun Velocity.toFloat() = x + override fun Float.toOffset() = Offset(this, 0f) + override fun Float.toVelocity() = Velocity(this, 0f) + } + +private val VerticalConverter = + object : SpaceVectorConverter { + override fun Offset.toFloat() = y + override fun Velocity.toFloat() = y + override fun Float.toOffset() = Offset(0f, this) + override fun Float.toVelocity() = Velocity(0f, this) + } 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 cc7a0b8e33b2..ce3e1db2c3d0 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 @@ -23,6 +23,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -427,4 +428,30 @@ class ElementTest { assertThat(barElement.sceneValues.keys).containsExactly(TestScenes.SceneA) assertThat(fooElement.sceneValues).isEmpty() } + + @Test + fun existingElementsDontRecomposeWhenTransitionStateChanges() { + var fooCompositions = 0 + + rule.testTransition( + fromSceneContent = { + SideEffect { fooCompositions++ } + Box(Modifier.element(TestElements.Foo)) + }, + toSceneContent = {}, + transition = { + spec = tween(4 * 16) + + scaleSize(TestElements.Foo, width = 2f, height = 0.5f) + translate(TestElements.Foo, x = 10.dp, y = 10.dp) + fade(TestElements.Foo) + } + ) { + before { assertThat(fooCompositions).isEqualTo(1) } + at(16) { assertThat(fooCompositions).isEqualTo(1) } + at(32) { assertThat(fooCompositions).isEqualTo(1) } + at(48) { assertThat(fooCompositions).isEqualTo(1) } + after { assertThat(fooCompositions).isEqualTo(1) } + } + } } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt new file mode 100644 index 000000000000..ce7db80db7da --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.view.viewmodel + +import android.app.smartspace.SmartspaceTarget +import android.provider.Settings +import android.widget.RemoteViews +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository +import com.android.systemui.communal.data.repository.FakeCommunalRepository +import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository +import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository +import com.android.systemui.communal.domain.interactor.CommunalInteractorFactory +import com.android.systemui.communal.domain.model.CommunalContentModel +import com.android.systemui.communal.shared.model.CommunalWidgetContentModel +import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.media.controls.ui.MediaHost +import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class CommunalEditModeViewModelTest : SysuiTestCase() { + @Mock private lateinit var mediaHost: MediaHost + + private lateinit var testScope: TestScope + + private lateinit var keyguardRepository: FakeKeyguardRepository + private lateinit var communalRepository: FakeCommunalRepository + private lateinit var tutorialRepository: FakeCommunalTutorialRepository + private lateinit var widgetRepository: FakeCommunalWidgetRepository + private lateinit var smartspaceRepository: FakeSmartspaceRepository + private lateinit var mediaRepository: FakeCommunalMediaRepository + + private lateinit var underTest: CommunalEditModeViewModel + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + testScope = TestScope() + + val withDeps = CommunalInteractorFactory.create() + keyguardRepository = withDeps.keyguardRepository + communalRepository = withDeps.communalRepository + tutorialRepository = withDeps.tutorialRepository + widgetRepository = withDeps.widgetRepository + smartspaceRepository = withDeps.smartspaceRepository + mediaRepository = withDeps.mediaRepository + + underTest = + CommunalEditModeViewModel( + withDeps.communalInteractor, + mediaHost, + ) + } + + @Test + fun communalContent_onlyWidgetsAreShownInEditMode() = + testScope.runTest { + tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) + + // Widgets available. + val widgets = + listOf( + CommunalWidgetContentModel( + appWidgetId = 0, + priority = 30, + providerInfo = mock(), + ), + CommunalWidgetContentModel( + appWidgetId = 1, + priority = 20, + providerInfo = mock(), + ), + ) + widgetRepository.setCommunalWidgets(widgets) + + // Smartspace available. + val target = Mockito.mock(SmartspaceTarget::class.java) + whenever(target.smartspaceTargetId).thenReturn("target") + whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER) + whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java)) + smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target)) + + // Media playing. + mediaRepository.mediaPlaying.value = true + + val communalContent by collectLastValue(underTest.communalContent) + + // Only Widgets are shown. + assertThat(communalContent?.size).isEqualTo(2) + assertThat(communalContent?.get(0)) + .isInstanceOf(CommunalContentModel.Widget::class.java) + assertThat(communalContent?.get(1)) + .isInstanceOf(CommunalContentModel.Widget::class.java) + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt new file mode 100644 index 000000000000..32f4d075a873 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.view.viewmodel + +import android.app.smartspace.SmartspaceTarget +import android.provider.Settings +import android.widget.RemoteViews +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository +import com.android.systemui.communal.data.repository.FakeCommunalRepository +import com.android.systemui.communal.data.repository.FakeCommunalTutorialRepository +import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository +import com.android.systemui.communal.domain.interactor.CommunalInteractorFactory +import com.android.systemui.communal.domain.model.CommunalContentModel +import com.android.systemui.communal.shared.model.CommunalWidgetContentModel +import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.media.controls.ui.MediaHost +import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository +import com.android.systemui.util.mockito.mock +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class CommunalViewModelTest : SysuiTestCase() { + @Mock private lateinit var mediaHost: MediaHost + + private lateinit var testScope: TestScope + + private lateinit var keyguardRepository: FakeKeyguardRepository + private lateinit var communalRepository: FakeCommunalRepository + private lateinit var tutorialRepository: FakeCommunalTutorialRepository + private lateinit var widgetRepository: FakeCommunalWidgetRepository + private lateinit var smartspaceRepository: FakeSmartspaceRepository + private lateinit var mediaRepository: FakeCommunalMediaRepository + + private lateinit var underTest: CommunalViewModel + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + testScope = TestScope() + + val withDeps = CommunalInteractorFactory.create() + keyguardRepository = withDeps.keyguardRepository + communalRepository = withDeps.communalRepository + tutorialRepository = withDeps.tutorialRepository + widgetRepository = withDeps.widgetRepository + smartspaceRepository = withDeps.smartspaceRepository + mediaRepository = withDeps.mediaRepository + + underTest = + CommunalViewModel( + withDeps.communalInteractor, + withDeps.tutorialInteractor, + mediaHost, + ) + } + + @Test + fun tutorial_tutorialNotCompletedAndKeyguardVisible_showTutorialContent() = + testScope.runTest { + // Keyguard showing, and tutorial not started. + keyguardRepository.setKeyguardShowing(true) + keyguardRepository.setKeyguardOccluded(false) + tutorialRepository.setTutorialSettingState( + Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED + ) + + val communalContent by collectLastValue(underTest.communalContent) + + assertThat(communalContent!!).isNotEmpty() + communalContent!!.forEach { model -> + assertThat(model is CommunalContentModel.Tutorial).isTrue() + } + } + + @Test + fun ordering_smartspaceBeforeUmoBeforeWidgets() = + testScope.runTest { + tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED) + + // Widgets available. + val widgets = + listOf( + CommunalWidgetContentModel( + appWidgetId = 0, + priority = 30, + providerInfo = mock(), + ), + CommunalWidgetContentModel( + appWidgetId = 1, + priority = 20, + providerInfo = mock(), + ), + ) + widgetRepository.setCommunalWidgets(widgets) + + // Smartspace available. + val target = Mockito.mock(SmartspaceTarget::class.java) + whenever(target.smartspaceTargetId).thenReturn("target") + whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER) + whenever(target.remoteViews).thenReturn(Mockito.mock(RemoteViews::class.java)) + smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target)) + + // Media playing. + mediaRepository.mediaPlaying.value = true + + val communalContent by collectLastValue(underTest.communalContent) + + // Order is smart space, then UMO, then widget content. + assertThat(communalContent?.size).isEqualTo(4) + assertThat(communalContent?.get(0)) + .isInstanceOf(CommunalContentModel.Smartspace::class.java) + assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java) + assertThat(communalContent?.get(2)) + .isInstanceOf(CommunalContentModel.Widget::class.java) + assertThat(communalContent?.get(3)) + .isInstanceOf(CommunalContentModel.Widget::class.java) + } +} diff --git a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml index 218735229a5d..7b9027004eea 100644 --- a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml +++ b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml @@ -22,7 +22,8 @@ android:focusable="true" android:clickable="true" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:visibility="invisible"> <com.android.systemui.scrim.ScrimView android:id="@+id/alternate_bouncer_scrim" diff --git a/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml index 34e7d0afcd97..f7c04b5366f8 100644 --- a/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml +++ b/packages/SystemUI/res/drawable/screenshare_options_spinner_background.xml @@ -26,10 +26,17 @@ </shape> </item> <item - android:drawable="@drawable/ic_ksh_key_down" - android:gravity="end|center_vertical" - android:textColor="?androidprv:attr/textColorPrimary" - android:width="@dimen/screenrecord_spinner_arrow_size" - android:height="@dimen/screenrecord_spinner_arrow_size" - android:end="20dp" /> + android:end="20dp" + android:gravity="end|center_vertical"> + <vector + android:width="@dimen/screenrecord_spinner_arrow_size" + android:height="@dimen/screenrecord_spinner_arrow_size" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?androidprv:attr/colorControlNormal"> + <path + android:fillColor="#FF000000" + android:pathData="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z" /> + </vector> + </item> </layer-list>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/shortcut_button_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_colored.xml index a21489cc47aa..bf908532ac17 100644 --- a/packages/SystemUI/res/drawable/shortcut_button_colored.xml +++ b/packages/SystemUI/res/drawable/shortcut_button_colored.xml @@ -22,8 +22,8 @@ <item> <shape android:shape="rectangle"> <corners android:radius="16dp"/> - <solid android:color="?androidprv:attr/colorSurface"/> + <solid android:color="?androidprv:attr/materialColorSurfaceBright"/> </shape> </item> </ripple> -</inset>
\ No newline at end of file +</inset> diff --git a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml index 2ff32b6ee9b5..f692ed975319 100644 --- a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml +++ b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml @@ -22,8 +22,8 @@ <item> <shape android:shape="rectangle"> <corners android:radius="16dp"/> - <solid android:color="?androidprv:attr/colorAccentPrimary"/> + <solid android:color="?androidprv:attr/materialColorPrimary"/> </shape> </item> </ripple> -</inset>
\ No newline at end of file +</inset> diff --git a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml new file mode 100644 index 000000000000..6c4d4fbcc1fe --- /dev/null +++ b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<inset xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> +<ripple android:color="?android:attr/colorControlHighlight" android:radius="24dp"> + <item> + <shape android:shape="oval"> + <size android:width="24dp" + android:height="24dp" /> + <solid android:color="?androidprv:attr/colorSurface"/> + </shape> + </item> +</ripple> +</inset> diff --git a/packages/SystemUI/res/layout/edit_widgets.xml b/packages/SystemUI/res/layout/edit_widgets.xml deleted file mode 100644 index 182e651aa66d..000000000000 --- a/packages/SystemUI/res/layout/edit_widgets.xml +++ /dev/null @@ -1,32 +0,0 @@ -<!-- - ~ Copyright (C) 2023 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> - -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/edit_widgets" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <Button - style="@android:Widget.DeviceDefault.Button.Colored" - android:id="@+id/add_widget" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:textSize="28sp" - android:text="@string/hub_mode_add_widget_button_text"/> - -</FrameLayout> diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml index 13425c9259de..dbcd2636134f 100644 --- a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml +++ b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml @@ -53,7 +53,7 @@ android:hint="@string/keyboard_shortcut_search_list_hint" android:textColorHint="?android:attr/textColorTertiary" /> - <ImageView + <ImageButton android:id="@+id/keyboard_shortcuts_search_cancel" android:layout_gravity="center_vertical|end" android:layout_width="wrap_content" @@ -61,7 +61,10 @@ android:layout_marginEnd="49dp" android:padding="16dp" android:contentDescription="@string/keyboard_shortcut_clear_text" - android:src="@drawable/ic_shortcutlist_search_button_cancel" /> + android:src="@drawable/ic_shortcutlist_search_button_cancel" + android:background="@drawable/shortcut_search_cancel_button" + style="@android:style/Widget.Material.Button.Borderless.Small" + android:pointerIcon="arrow" /> </FrameLayout> <HorizontalScrollView @@ -82,15 +85,13 @@ android:id="@+id/shortcut_system" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="12dp" style="@style/ShortCutButton" - android:text="@string/keyboard_shortcut_search_category_system"/> + android:text="@string/keyboard_shortcut_search_category_system" /> <Button android:id="@+id/shortcut_input" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="12dp" style="@style/ShortCutButton" android:text="@string/keyboard_shortcut_search_category_input"/> @@ -98,7 +99,6 @@ android:id="@+id/shortcut_open_apps" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="12dp" style="@style/ShortCutButton" android:text="@string/keyboard_shortcut_search_category_open_apps"/> @@ -106,7 +106,6 @@ android:id="@+id/shortcut_specific_app" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="12dp" style="@style/ShortCutButton" android:text="@string/keyboard_shortcut_search_category_current_app"/> </LinearLayout> diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml index 7e03bd9d4325..ca0fb85beb6e 100644 --- a/packages/SystemUI/res/layout/super_notification_shade.xml +++ b/packages/SystemUI/res/layout/super_notification_shade.xml @@ -30,7 +30,6 @@ android:id="@+id/scrim_behind" android:layout_width="match_parent" android:layout_height="match_parent" - android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> @@ -38,7 +37,6 @@ android:id="@+id/scrim_notifications" android:layout_width="match_parent" android:layout_height="match_parent" - android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> @@ -78,7 +76,6 @@ android:id="@+id/scrim_in_front" android:layout_width="match_parent" android:layout_height="match_parent" - android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> @@ -119,11 +116,6 @@ android:inflatedId="@+id/multi_shade" android:layout="@layout/multi_shade" /> - <include layout="@layout/alternate_bouncer" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="invisible" /> - <com.android.systemui.biometrics.AuthRippleView android:id="@+id/auth_ripple" android:layout_width="match_parent" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 33b241b161b6..b0c4fa56a73a 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth gekoppel."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth-toestelikoon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klik om toestelbesonderhede op te stel."</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterypersentasie is onbekend."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Gekoppel aan <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Gekoppel aan <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gebruik Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Gekoppel"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gestoor"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Oudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kopstuk"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index be58b528a8af..b17455241d57 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ብሉቱዝ ተያይዟል።"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"የብሉቱዝ መሣሪያ አዶ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"የመሣሪያ ዝርዝርን ለማዋቀር ጠቅ ያድርጉ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"የባትሪ መቶኛ አይታወቅም።"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ከ<xliff:g id="BLUETOOTH">%s</xliff:g> ጋር ተገናኝቷል።"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"ከ<xliff:g id="CAST">%s</xliff:g> ጋር ተገናኝቷል።"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ብሉቱዝን ይጠቀሙ"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ተገናኝቷል"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ተቀምጧል"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ባትሪ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ኦዲዮ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ማዳመጫ"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ኃይል በመሙላት ላይ • በ<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ውስጥ ይሞላል"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"የጋራ አጋዥ ሥልጠናውን ለመጀመር ወደ ግራ ያንሸራትቱ።"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ምግብር መራጩን ክፈት"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ምግብርን አስወግድ"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"በቅርብ ጊዜ በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ጥቅም ላይ ውሏል"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 2dbd3e95604e..0b53b41ffa7d 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"تم توصيل البلوتوث."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"رمز الجهاز الذي يتضمّن بلوتوث"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"انقر هنا لضبط إعدادات الجهاز."</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"نسبة شحن البطارية غير معروفة."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"متصل بـ <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"تم الاتصال بـ <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"استخدام البلوتوث"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"متّصل"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"مستوى طاقة البطارية <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"سماعة الرأس"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن سريعًا • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن ببطء • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • جارٍ الشحن • ستمتلئ البطارية خلال <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"مرِّر سريعًا لليمين لبدء الدليل التوجيهي العام."</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 9bad7b90dcc3..e593a5bb731b 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ব্লুটুথ সংযোগ হ’ল।"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ব্লুটুথ ডিভাইচৰ চিহ্ন"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ডিভাইচৰ সবিশেষ কনফিগাৰ কৰিবলৈ ক্লিক কৰক"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"বেটাৰীৰ চাৰ্জৰ শতাংশ অজ্ঞাত।"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>ৰ লগত সংযোগ কৰা হ’ল।"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>ত সংযোগ হ’ল।"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ব্লুটুথ ব্যৱহাৰ কৰক"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"সংযুক্ত আছে"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ছেভ কৰা হৈছে"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"বেটাৰী <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিঅ’"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডছেট"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • লাহে লাহে চাৰ্জ হৈ আছে • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ত সম্পূৰ্ণ হ’ব"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চাৰ্জ হৈ আছে • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ত সম্পূৰ্ণ হ’ব"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"সম্প্ৰদায় সম্পৰ্কীয় নিৰ্দেশনা আৰম্ভ কৰিবলৈ বাওঁফালে ছোৱাইপ কৰক"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ৱিজেট বাছনিকৰ্তাটো খোলক"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"এটা ৱিজেট আঁতৰাওক"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"শেহতীয়াকৈ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)এ ব্যৱহাৰ কৰিছে"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string> </resources> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index dfba8c2fbe79..4a2a595c8893 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth qoşulub."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth cihazı ikonası"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Cihaz təfərrüatlarını konfiqurasiya etmək üçün klikləyin"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareyanın faizi naməlumdur."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> üzərindən qoşuldu."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> cihazına qoşulub."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth aç"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Qoşulub"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Yadda saxlandı"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Qulaqlıq"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sürətlə şarj edilir • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Asta şarj edilir • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Şarj edilir • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> sonra dolacaq"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"İcma təlimatını başlatmaq üçün sola sürüşdürün"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 4060a8d0db14..c7f2eafb9a4f 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je priključen."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona Bluetooth uređaja"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknite da biste konfigurisali detalje o uređaju"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procenat napunjenosti baterije nije poznat."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezani ste sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani smo sa uređajem <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Brzo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo se puni • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Puni se • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do kraja punjenja"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Prevucite ulevo da biste započeli zajednički vodič"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Otvori birač vidžeta"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Ukloni vidžet"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koriste <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">"Nedavno koristila aplikacija <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index f5490010e653..41d674416f86 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-сувязь."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Значок прылады з Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Націсніце, каб задаць падрабязныя налады прылады"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Працэнт зараду акумулятара невядомы."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Падлучаны да <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Ёсць падключэнне да <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Выкарыстоўваць Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Падключана"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Захавана"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Узровень зараду: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Гук"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе хуткая зарадка • Поўны зарад праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе павольная зарадка • Поўны зарад праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ідзе зарадка • Поўны зарад праз <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Правядзіце пальцам па экране ўлева, каб азнаёміцца з дапаможнікам"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index ceb98a04a083..8f64831df295 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth е включен."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Икона за устройство с Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Кликнете, за да конфигурирате подробностите за устройството"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентът на батерията е неизвестен."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Има връзка с <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Установена е връзка с/ъс <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Използване на Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Установена е връзка"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Запазено"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батерия: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарежда се бързо • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарежда се бавно • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарежда се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до пълно зареждане"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Прекарайте пръст наляво, за да стартирате общия урок"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index c1ccba5fdb0c..809a25d583bf 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ব্লুটুথ সংযুক্ত হয়েছে৷"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ব্লুটুথ ডিভাইসের আইকন"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ডিভাইসের বিবরণ কনফিগার করতে ক্লিক করুন"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ব্যাটারি কত শতাংশ আছে তা জানা যায়নি।"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>এ সংযুক্ত হয়ে আছে।"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> এর সাথে সংযুক্ত৷"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ব্লুটুথ ব্যবহার করুন"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"কানেক্ট করা আছে"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"সেভ করা আছে"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"চার্জ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"অডিও"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"হেডসেট"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • দ্রুত চার্জ হচ্ছে • পুরো চার্জ হতে <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> লাগবে"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ধীরে চার্জ হচ্ছে • পুরো চার্জ হতে <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> লাগবে"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • চার্জ হচ্ছে • পুরো চার্জ হতে আরও <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> সময় লাগবে"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"কমিউনিটি টিউটোরিয়াল চালু করতে বাঁদিকে সোয়াইপ করুন"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 08656e5b9340..f97b05569e57 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth je povezan."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona Bluetooth uređaja"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknite da konfigurirate detalje uređaja"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak napunjenosti baterije nije poznat"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezan na <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezan na <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sačuvano"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Brzo punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sporo punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Punjenje • Potpuna napunjenost za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Prevucite ulijevo da pokrenete zajednički vodič"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Otvaranje birača vidžeta"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Uklanjanje vidžeta"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nedavno je koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi aplikacija <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">"Nedavno je koristila aplikacija <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 443c2eee9ef3..ba82dfe47298 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connectat."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icona de dispositiu Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Fes clic per configurar els detalls del dispositiu"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Es desconeix el percentatge de bateria."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"S\'ha connectat a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Està connectat amb <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utilitza\'l"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connectat"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Desat"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Àudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculars"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant ràpidament • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant • Es completarà d\'aquí a <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Llisca cap a l\'esquerra per iniciar el tutorial de la comunitat"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index ada9c3cca76d..2201d64676b9 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Rozhraní Bluetooth je připojeno."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona zařízení Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknutím nakonfigurujete podrobnosti o zařízení"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procento baterie není známé."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Připojeno k zařízení <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Jste připojeni k zařízení <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Použít Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Připojeno"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uloženo"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Sluchátka"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Rychlé nabíjení • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Pomalé nabíjení • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíjení • Plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Přejetím doleva spustíte komunitní výukový program"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Otevřít výběr widgetu"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Odstranit widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nedávno použila aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Právě používán aplikací <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">"Nedávno použila aplikace <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index f6f40d04c4c0..14bce296477e 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth tilsluttet."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikon for Bluetooth-enhed"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klik for at konfigurere enhedsoplysninger"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriniveauet er ukendt."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tilsluttet <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Forbundet til <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Brug Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Der er oprettet forbindelse"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gemt"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader hurtigt • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader langsomt • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Oplader • Fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Stryg mod venstre for at starte den fælles vejledning"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index f8709c8e3597..2d9a83023018 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Mit Bluetooth verbunden"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Symbol des Bluetooth-Geräts"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klicke, um das Gerätedetail zu konfigurieren"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akkustand unbekannt."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Mit <xliff:g id="BLUETOOTH">%s</xliff:g> verbunden"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Verbunden mit <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth verwenden"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Verbunden"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gespeichert"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -398,10 +406,8 @@ <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Wird geladen • Voll in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Widget-Auswahl öffnen"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Widget entfernen"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string> @@ -1210,8 +1216,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Kürzlich von <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Verwendet von <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">"Kürzlich von <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index c42f04dc9b8b..72fe0804889f 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Το Bluetooth είναι συνδεδεμένο."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Εικονίδιο συσκευής Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Κάντε κλικ για να διαμορφώσετε τις λεπτομέρειες συσκευής"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Άγνωστο ποσοστό μπαταρίας."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Συνδέθηκε στο <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Συνδέθηκε σε <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Χρήση Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Συνδέθηκε"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Αποθηκεύτηκε"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Μπαταρία <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ήχος"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ακουστικά"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Αργή φόρτιση • Πλήρης φόρτιση σε <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Φόρτιση • Πλήρης φόρτιση σε <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Σύρετε προς τα αριστερά για να ξεκινήσετε τον κοινόχρηστο οδηγό"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Άνοιγμα του εργαλείου επιλογής γραφικών στοιχείων"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Αφαίρεση ενός widget"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Χρησιμοποιήθηκε πρόσφατα από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index cc1b908d7ee8..d7062e157c4a 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth device icon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Click to configure device detail"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Swipe left to start the communal tutorial"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Open the widget picker"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remove a widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <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">"Recently used by <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index c3c2d1753bfe..9fcf1a3fc68e 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth device icon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Click to configure device detail"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index cc1b908d7ee8..d7062e157c4a 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth device icon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Click to configure device detail"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Swipe left to start the communal tutorial"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Open the widget picker"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remove a widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <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">"Recently used by <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index cc1b908d7ee8..d7062e157c4a 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth device icon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Click to configure device detail"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Charging • Full in <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Swipe left to start the communal tutorial"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Open the widget picker"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remove a widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <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">"Recently used by <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 1badbb35fb57..a68c7c557fcf 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connected."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth device icon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Click to configure device detail"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Battery percentage unknown."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connected to <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connected to <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Use Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connected"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e0ad6ff8ac01..03acc6a43cc2 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ícono de dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Haz clic para configurar los detalles del dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Se desconoce el porcentaje de la batería."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lento • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando • Se completará en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Desliza el dedo a la izquierda para iniciar el instructivo comunal"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Abre el selector de widgets"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Quita el widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Uso reciente en <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <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">"Uso reciente en <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 5685b31b679d..18131372ec40 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icono de dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Haz clic para configurar la información del dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentaje de batería desconocido."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga rápida • En <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> terminará de cargarse"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • En <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> terminará de cargarse"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando • Carga completa en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Desliza hacia la izquierda para iniciar el tutorial de la comunidad"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 86f982b8437e..57dbb96c7143 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth on ühendatud."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth-seadme ikoon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klõpsake seadme üksikasjade konfigureerimiseks"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Aku laetuse protsent on teadmata."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ühendatud: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Ühendatud ülekandega <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Kasuta Bluetoothi"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ühendatud"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvestatud"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Heli"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Peakomplekt"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Kiirlaadimine • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Aeglane laadimine • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laadimine • Täis <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> pärast"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ühise õpetuse käivitamiseks pühkige vasakule"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index fb89c044341d..0902354bfa82 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetootha konektatuta."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth bidezko gailuaren ikonoa"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Gailuaren xehetasuna konfiguratzeko, sakatu hau"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Bateriaren ehunekoa ezezaguna da."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> gailura konektatuta."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Hona konektatuta: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Erabili Bluetootha"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Konektatuta"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gordeta"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audioa"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Entzungailua"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Bizkor kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mantso kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Kargatzen • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> guztiz kargatu arte"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Tutorial komuna hasteko, pasatu hatza ezkerrera"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 7ab2ef156bc9..f42bf5038298 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"بلوتوث متصل است."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"نماد دستگاه بلوتوث"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"برای پیکربندی جزئیات دستگاه کلیک کنید"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"درصد شارژ باتری مشخص نیست."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"به <xliff:g id="BLUETOOTH">%s</xliff:g> متصل شد."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"به <xliff:g id="CAST">%s</xliff:g> متصل شد."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"استفاده از بلوتوث"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"متصل"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ذخیرهشده"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"هدست"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • درحال شارژ کردن آهسته • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> تا شارژ کامل"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • درحال شارژ شدن • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> تا شارژ کامل"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"برای شروع آموزش گامبهگام عمومی، تند بهچپ بکشید"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"باز کردن انتخابگر ابزارک"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"حذف ابزارک"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"اخیراً <xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده کرده است (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پسزمینه صفحهکلید"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"سطح %1$d از %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 9023d6331ac8..ae3ac060d494 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth yhdistetty."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth-laitekuvake"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Määritä laitteen asetukset klikkaamalla"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akun varaustaso ei tiedossa."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Yhteys: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Yhdistetty kohteeseen <xliff:g id="CAST">%s</xliff:g>"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Käytä Bluetoothia"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Yhdistetty"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Tallennettu"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ääni"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Latautuu nopeasti • Täynnä <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> päästä"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Latautuu hitaasti • Täynnä <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> päästä"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Latautuu • Täynnä <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> päästä"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Aloita yhteisöesittely pyyhkäisemällä vasemmalle"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index f63f96fd739d..286753d01041 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connecté"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icône de l\'appareil Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Cliquez pour configurer les détails de l\'appareil"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la pile inconnu."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utiliser le Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connecté"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Écouteurs"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"En recharge rapide : <xliff:g id="PERCENTAGE">%2$s</xliff:g> • Terminée dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"En recharge lente : <xliff:g id="PERCENTAGE">%2$s</xliff:g> • Terminée <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge en cours… • Se terminera dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Balayer l\'écran vers la gauche pour démarrer le tutoriel communautaire"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 3d765b2a3a32..7f4e4cc36d5c 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth connecté"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icône de l\'appareil Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Cliquer pour configurer les détails de l\'appareil"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pourcentage de la batterie inconnu."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connecté à : <xliff:g id="BLUETOOTH">%s</xliff:g>"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connecté à <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Utiliser le Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Connecté"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Enregistré"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Casque"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge lente • Temps restant : <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge • Temps restant : <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Balayer vers la gauche pour démarrer le tutoriel collectif"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Ouvrez le sélecteur de widgets"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Retirez un widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En cours d\'utilisation par <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">"Récemment utilisé par <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 5846c94f6f26..88d0a314789d 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icona do dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Facer clic para configurar os detalles do dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Descoñécese a porcentaxe da batería."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Dispositivo conectado: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Estableceuse a conexión"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Gardouse"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando rapidamente • A carga completarase en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lentamente • A carga completarase en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando • A carga completarase en <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Pasa o dedo cara á esquerda para iniciar o titorial comunitario"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 71177029ac4c..92638a22fc79 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"બ્લૂટૂથ કનેક્ટ થયું."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"બ્લૂટૂથ ડિવાઇસનું આઇકન"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ડિવાઇસની વિગત ગોઠવવા માટે ક્લિક કરો"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"બૅટરીની ટકાવારી અજાણ છે."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> થી કનેક્ટ થયાં."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> થી કનેક્ટ કરેલ."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"બ્લૂટૂથનો ઉપયોગ કરો"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"કનેક્ટેડ છે"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"સાચવેલું"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> બૅટરી"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ઑડિયો"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"હૅડસેટ"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ધીમેથી ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં ચાર્જ થઈ જશે"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ચાર્જ થઈ રહ્યું છે • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>માં પૂરું ચાર્જ થઈ જશે"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"કૉમ્યુનલ ટ્યૂટૉરિઅલ શરૂ કરવા માટે ડાબે સ્વાઇપ કરો"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"વિજેટ પિકર ખોલો"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"કોઈ વિજેટ કાઢી નાખો"</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> @@ -723,7 +729,7 @@ <string name="switch_bar_off" msgid="5669805115416379556">"બંધ"</string> <string name="tile_unavailable" msgid="3095879009136616920">"ઉપલબ્ધ નથી"</string> <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"વધુ જાણો"</string> - <string name="nav_bar" msgid="4642708685386136807">"નેવિગેશન બાર"</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> @@ -742,7 +748,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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) દ્વારા તાજેતરમાં ઉપયોગ કરવામાં આવ્યો"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string> </resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index fa44aed32672..213457fef803 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लूटूथ कनेक्ट किया गया."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ब्लूटूथ डिवाइस का आइकॉन"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"डिवाइस की जानकारी कॉन्फ़िगर करने के लिए क्लिक करें"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"इस बारे में जानकारी नहीं है कि अभी बैटरी कितने प्रतिशत चार्ज है."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> से कनेक्ट किया गया."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> से कनेक्ट है."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्लूटूथ इस्तेमाल करें"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट है"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव किया गया"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बैटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • तेज़ चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • धीरे चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • चार्ज हो रहा है • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> में पूरा चार्ज हो जाएगा"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"कम्यूनिटी ट्यूटोरियल शुरू करने के लिए, बाईं ओर स्वाइप करें"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"विजेट पिकर को खोलें"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"विजेट को हटाएं"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"हाल ही में, <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ने इस्तेमाल किया"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index c3a4ec29ec86..cf86c466b645 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth povezan."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona Bluetooth uređaja"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknite da biste konfigurirali pojedinosti o uređaju"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Postotak baterije nije poznat."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Spojen na <xliff:g id="BLUETOOTH">%s</xliff:g> ."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Povezani ste sa sljedećim uređajem: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Uključi"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Spremljeno"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • brzo punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • sporo punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • punjenje • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> do napunjenosti"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Prijeđite prstom ulijevo da biste pokrenuli zajednički vodič"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Otvaranje alata za odabir widgeta"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Uklanjanje widgeta"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi: <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">"Nedavno koristila aplikacija <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 5552b5134f62..6f1d2c609bb0 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth csatlakoztatva."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth-eszköz ikon"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kattintson az eszköz beállításainak megadásához"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Az akkumulátor töltöttségi szintje ismeretlen."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Csatlakoztatva a következőhöz: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Csatlakozva a következőhöz: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth használata"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Csatlakozva"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Mentve"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hang"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Gyors töltés • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lassú töltés • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Töltés • A teljes töltöttségig: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Csúsztasson gyorsan balra a közösségi útmutató elindításához"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"A modulválasztó megnyitása"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"A modul eltávolítása"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Legutóbb használta: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Használatban a következő által: <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">"Legutóbb használta: <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string> </resources> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 714d50027293..8ceeb4b187bb 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-ը միացված է:"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth սարքի պատկերակ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Սեղմեք՝ սարքի մանրամասները կազմաձևելու համար"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Մարտկոցի լիցքի մակարդակն անհայտ է։"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Միացված է <xliff:g id="BLUETOOTH">%s</xliff:g>-ին:"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Միացված է <xliff:g id="CAST">%s</xliff:g>-ին:"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Միացնել Bluetooth-ը"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Միացված է"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Պահված է"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Մարտկոցի լիցքը՝ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Աուդիո"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ականջակալ"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Արագ լիցքավորում • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Դանդաղ լիցքավորում • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Լիցքավորում • Մնացել է <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Թերթեք ձախ՝ ուղեցույցը գործարկելու համար"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 1ff866e203bf..285bb3935b33 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth terhubung."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikon perangkat Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klik untuk mengonfigurasi detail perangkat"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Persentase baterai tidak diketahui."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Terhubung ke <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Terhubung ke <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gunakan Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Terhubung"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi daya dengan cepat • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi daya dengan lambat • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengisi daya • Penuh dalam waktu <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Geser ke kiri untuk memulai tutorial komunal"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 82e470f2455c..2cf9237766ac 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth tengt."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Tákn Bluetooth-tækis"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Smelltu til að stilla tækjaupplýsingar"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Staða rafhlöðu óþekkt."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tengt við <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Tengt við <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Nota Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Tengt"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Vistað"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hljóð"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Höfuðtól"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hraðhleðsla • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hæg hleðsla • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Í hleðslu • Full hleðsla eftir <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Strjúktu til vinstri til að hefja samfélagsleiðsögnina"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 50fc1ee3ebe0..4912a53f8c6d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth collegato."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icona del dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Fai clic per configurare i dettagli del dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentuale della batteria sconosciuta."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Connesso a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Connesso a: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usa Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Dispositivo connesso"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Dispositivo salvato"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batteria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auricolare"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ricarica veloce • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ricarica lenta • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • In carica • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> alla ricarica completa"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Scorri a sinistra per iniziare il tutorial della community"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 718cfb4bdf3a..eef614225afe 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth מחובר."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"סמל של מכשיר Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"יש ללחוץ כדי להגדיר את פרטי המכשיר"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"אחוז טעינת הסוללה לא ידוע."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"התבצע חיבור אל <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"מחובר אל <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"מחובר"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"נשמר"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> סוללה"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"אודיו"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"אוזניות"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה מהירה • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה איטית • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • בטעינה • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> עד לסיום"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"אפשר להחליק שמאלה כדי להפעיל את המדריך המשותף"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index a699f93a61ee..eaf719a49f36 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetoothに接続済み。"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth デバイスのアイコン"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"クリックしてデバイスの詳細を設定します"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"バッテリー残量は不明です。"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>に接続しました。"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>に接続されています。"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth を使用"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"接続しました"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"保存しました"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"バッテリー <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"オーディオ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ヘッドセット"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 低速充電中 • 完了まで <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 充電中 • フル充電まで <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"左にスワイプすると、コミュニティ チュートリアルが開始します"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ウィジェット選択ツールを開きます"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ウィジェットを削除します"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"<xliff:g id="APP_NAME">%1$s</xliff:g> が最近使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index cf3a740d0f65..b3295e3220f9 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth დაკავშირებულია."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth მოწყობილობის ხატულა"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"დააწკაპუნეთ მოწყობილობის დეტალების კონფიგურირებისთვის"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ბატარეის პროცენტული მაჩვენებელი უცნობია."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"დაკავშირებულია <xliff:g id="BLUETOOTH">%s</xliff:g>-თან."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"დაკავშირებულია მოწყობილობასთან: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-ის გამოყენება"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"დაკავშირებული"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"შენახული"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ბატარეა"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"აუდიო"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ყურსაცვამი"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • სწრაფად იტენება • სრულ დატენვამდე <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ნელა იტენება • სრულ დატენვამდე <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • იტენება • სრულ დატენვამდე <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"გადაფურცლეთ მარცხნივ, რათა დაიწყოთ საერთო სახელმძღვანელო"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index d8eaba0c3fde..3dc2ebcee7b6 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth қосылған."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth құрылғысы белгішесі"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Құрылғы деректерін конфигурациялау үшін басыңыз."</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея зарядының мөлшері белгісіз."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> қосылған."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> трансляциясына қосылды."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-ты пайдалану"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Қосылды"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сақталды"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батарея деңгейі: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Aудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жылдам зарядтау • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Баяу зарядталуда • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядталып жатыр. • Толуына <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> қалды."</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ортақ оқулықты ашу үшін солға қарай сырғытыңыз."</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index 6c936857bc91..6ba41b83d4ed 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"បានតភ្ជាប់ប៊្លូធូស។"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"រូបឧបករណ៍ប៊្លូធូស"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ចុចដើម្បីកំណត់រចនាសម្ព័ន្ធព័ត៌មានលម្អិតអំពីឧបករណ៍"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"មិនដឹងអំពីភាគរយថ្មទេ។"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"បានភ្ជាប់ទៅ <xliff:g id="BLUETOOTH">%s</xliff:g> ។"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"បានភ្ជាប់ទៅ <xliff:g id="CAST">%s</xliff:g>"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ប្រើប៊្លូធូស"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"បានភ្ជាប់"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"បានរក្សាទុក"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ថ្ម <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"សំឡេង"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"កាស"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • កំពុងសាកថ្មយឺត • ពេញក្នុងរយៈពេល <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • កំពុងសាកថ្ម • ពេញក្នុងរយៈពេល <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"អូសទៅឆ្វេង ដើម្បីចាប់ផ្ដើមមេរៀនសហគមន៍"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"បើកផ្ទាំងជ្រើសរើសធាតុក្រាហ្វិក"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ដកធាតុក្រាហ្វិកចេញ"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"បានប្រើនាពេលថ្មីៗនេះដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ពន្លឺក្រោយក្ដារចុច"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index ff2d4c5bae86..080ce108e46c 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ಬ್ಲೂಟೂತ್ ಸಂಪರ್ಕಗೊಂಡಿದೆ."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ಬ್ಲೂಟೂತ್ ಸಾಧನ ಐಕಾನ್"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ಸಾಧನದ ವಿವರಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ಬ್ಯಾಟರಿ ಶೇಕಡಾವಾರು ತಿಳಿದಿಲ್ಲ."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ಬ್ಲೂಟೂತ್ ಬಳಸಿ"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ಬ್ಯಾಟರಿ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ಆಡಿಯೋ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ಹೆಡ್ಸೆಟ್"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ವೇಗವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ನಿಧಾನವಾಗಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ಸಮಯದಲ್ಲಿ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ದಲ್ಲಿ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"ಸಮುದಾಯದ ಟ್ಯುಟೋರಿಯಲ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಎಡಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ವಿಜೆಟ್ ಪಿಕರ್ ತೆರೆಯಿರಿ"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ವಿಜೆಟ್ ತೆಗೆದುಹಾಕಿ"</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> @@ -509,7 +514,7 @@ <string name="sound_settings" msgid="8874581353127418308">"ಧ್ವನಿ & ವೈಬ್ರೇಷನ್"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ವಾಲ್ಯೂಮ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮಟ್ಟಕ್ಕೆ ತಗ್ಗಿಸಲಾಗಿದೆ"</string> - <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ಹೆಡ್ಫೋನ್ನ ವಾಲ್ಯೂಮ್ ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಿನ ಸಮಯದವರೆಗೆ ಅಧಿಕವಾಗಿದೆ"</string> + <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ಶಿಫಾರಸು ಮಾಡಿದ್ದಕ್ಕಿಂತಲೂ ದೀರ್ಘಕಾಲ ಹೆಡ್ಫೋನ್ನ ವಾಲ್ಯೂಮ್ ಹೆಚ್ಚಿಗೆ ಇದೆ"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ಹೆಡ್ಫೋನ್ನ ವಾಲ್ಯೂಮ್ ಈ ವಾರದ ಮಟ್ಟಿಗೆ ಸುರಕ್ಷಿತ ಮಿತಿಯನ್ನು ಮೀರಿದೆ"</string> <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ಆಲಿಸುತ್ತಿರಿ"</string> <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ವಾಲ್ಯೂಮ್ ತಗ್ಗಿಸಿ"</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_NAME">%1$s</xliff:g> ಇದನ್ನು ಬಳಸಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್ಲೈಟ್"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ddab1749038d..917781662a20 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"블루투스가 연결되었습니다."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"블루투스 기기 아이콘"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"기기 세부정보를 구성하려면 클릭하세요."</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"배터리 잔량을 알 수 없습니다."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>에 연결되었습니다."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>에 연결됨"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"블루투스 사용"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"연결됨"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"저장됨"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"배터리 <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"오디오"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"헤드셋"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 고속 충전 중 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 저속 충전 중 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 충전 중 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> 후 충전 완료"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"공동 튜토리얼을 시작하려면 왼쪽으로 스와이프하세요"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 90ba042e4565..e58cf593bde7 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth байланышта"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth түзмөгүнүн сүрөтчөсү"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Түзмөктүн чоо-жайын конфигурациялоо үчүн чыкылдатыңыз"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарея кубатынын деңгээли белгисиз."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> менен туташкан."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> менен туташты."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Иштетүү"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Туташты"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сакталды"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Батареянын деңгээли <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Тез кубатталууда • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Жай кубатталууда • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Кубатталууда • Толгонго чейин <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> калды"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Жалпы үйрөткүчтү иштетүү үчүн солго сүрүңүз"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index bdd0f2e807e7..0c220cce1b86 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ເຊື່ອມຕໍ່ Bluetooth ແລ້ວ."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ໄອຄອນອຸປະກອນ Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ຄລິກເພື່ອຕັ້ງຄ່າລາຍລະອຽດອຸປະກອນ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ບໍ່ຮູ້ເປີເຊັນແບັດເຕີຣີ."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"ເຊື່ອມຕໍ່ຫາ <xliff:g id="BLUETOOTH">%s</xliff:g> ແລ້ວ."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"ເຊື່ອມຕໍ່ຫາ <xliff:g id="CAST">%s</xliff:g> ແລ້ວ."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ໃຊ້ Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ເຊື່ອມຕໍ່ແລ້ວ"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ບັນທຶກແລ້ວ"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"ແບັດເຕີຣີ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ສຽງ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ຊຸດຫູຟັງ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index d86eeb933558..b1139a2bd4fc 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"„Bluetooth“ prijungtas."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"„Bluetooth“ įrenginio piktograma"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Spustelėkite, jei norite konfigūruoti išsamią įrenginio informaciją"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumuliatoriaus energija procentais nežinoma."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Prisijungta prie „<xliff:g id="BLUETOOTH">%s</xliff:g>“."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Prisijungta prie <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"„Bluetooth“ naudojimas"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Prisijungta"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Išsaugota"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Garsas"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Virtualiosios realybės įrenginys"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sparčiai įkraunama • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lėtai įkraunama • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Įkraunama • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> iki visiško įkrovimo"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Perbraukite kairėn, paleistumėte bendruomenės mokomąją medžiagą"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index a98cba0a58d7..03d6237f9125 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth savienojums ir izveidots."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth ierīces ikona"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Lai konfigurētu ierīces informāciju, noklikšķiniet"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Akumulatora uzlādes līmenis procentos nav zināms."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ir izveidots savienojum ar <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Savienots ar ierīci <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Izmantot Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Savienojums izveidots"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saglabāta"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Austiņas"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ātrā uzlāde • Laiks līdz pilnai uzlādei: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lēnā uzlāde • Laiks līdz pilnai uzlādei: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Notiek uzlāde • Laiks līdz pilnai uzlādei: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Velciet pa kreisi, lai palaistu kopienas pamācību."</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 0464bb34e09b..3374ba335b44 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth е поврзан."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Икона за уред со Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Кликнете за да ги конфигурирате деталите за уредот"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Процентот на батеријата е непознат."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Поврзано со <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Поврзано со <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Користи Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Поврзано"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Зачувано"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батерија"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалки"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index b4ff31416534..6e70f84df206 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ബ്ലൂടൂത്ത് കണക്റ്റുചെയ്തു."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth ഉപകരണ ഐക്കൺ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ഉപകരണത്തിന്റെ വിശദാംശങ്ങൾ കോൺഫിഗർ ചെയ്യാൻ ക്ലിക്ക് ചെയ്യുക"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ബാറ്ററി ശതമാനം അജ്ഞാതമാണ്."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth ഉപയോഗിക്കുക"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"കണക്റ്റ് ചെയ്തു"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"സംരക്ഷിച്ചു"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ബാറ്ററി"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ഓഡിയോ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ഹെഡ്സെറ്റ്"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • പതുക്കെ ചാർജ് ചെയ്യുന്നു • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-ൽ പൂർത്തിയാകും"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ചാർജ് ചെയ്യുന്നു • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-ൽ പൂർത്തിയാകും"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"കമ്മ്യൂണൽ ട്യൂട്ടോറിയൽ ആരംഭിക്കാൻ ഇടത്തോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"വിജറ്റ് പിക്കർ തുറക്കുക"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"വിജറ്റ് നീക്കം ചെയ്യുക"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) അടുത്തിടെ ഉപയോഗിച്ചു"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്ലൈറ്റ്"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string> </resources> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 42b0caefee97..93538c119eb6 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth холбогдсон."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth төхөөрөмжийн дүрс тэмдэг"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Төхөөрөмжийн дэлгэрэнгүйг тохируулахын тулд товшино уу"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Батарейн хувь тодорхойгүй байна."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>-тай холбогдсон."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>-д холбогдсон."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth-г ашиглах"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Холбогдсон"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Хадгалсан"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> батарей"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Чихэвч"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Хурдтай цэнэглэж байна • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Удаан цэнэглэж байна • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Цэнэглэж байна • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>-н дараа дүүрнэ"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Нийтийн практик хичээлийг эхлүүлэхийн тулд зүүн тийш шударна уу"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index ffa36a40c17d..32c27ac0e828 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लूटूथ कनेक्ट केले."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ब्लूटूथ डिव्हाइस आयकन"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"डिव्हाइसचे तपशील कॉंफिगर करण्यासाठी क्लिक करा"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"बॅटरीच्या चार्जिंगची टक्केवारी माहित नाही."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> शी कनेक्ट केले."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> शी कनेक्ट केले."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्लूटूथ वापरा"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट केले"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेव्ह केले"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> बॅटरी"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडिओ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • हळू चार्ज होत आहे • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मध्ये पूर्ण होईल"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • चार्ज होत आहे • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मध्ये पूर्ण होईल"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"सामुदायिक ट्यूटोरियल सुरू करण्यासाठी डावीकडे स्वाइप करा"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"विजेट पिकर उघडा"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"विजेट काढून टाका"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"अलीकडे <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ने वापरले"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string> </resources> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 7e0bba46bd8e..62efce1cd8f0 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth disambungkan."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikon peranti Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klik untuk mengkonfigurasi butiran peranti"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Peratusan kuasa bateri tidak diketahui."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Disambungkan kepada <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Disambungkan ke <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gunakan Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Disambungkan"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Disimpan"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Set Kepala"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengecas dengan perlahan • Penuh dalam masa <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mengecas • Penuh dalam masa <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Leret ke kiri untuk memulakan tutorial umum"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Buka pemilih widget"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Alih keluar widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Digunakan baru-baru ini oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Digunakan oleh <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">"Digunakan baru-baru ini oleh <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 9b3f6ca18593..6dd247dd71a6 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ဘလူးတုသ်ချိတ်ဆက်ထားမှု"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ဘလူးတုသ်သုံးစက် သင်္ကေတ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"စက်အသေးစိတ်ကို စီစဉ်သတ်မှတ်ရန် နှိပ်ပါ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ဘက်ထရီရာခိုင်နှုန်းကို မသိပါ။"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>သို့ ချိတ်ဆက်ထား"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> သို့ချိတ်ဆက်ထားပါသည်။"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ဘလူးတုသ်သုံးရန်"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ချိတ်ဆက်ထားသည်"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"သိမ်းထားသည်"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ဘက်ထရီ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"အသံ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"မိုက်ခွက်ပါနားကြပ်"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • အမြန်အားသွင်းနေသည် • အားပြည့်ရန် <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> လိုသည်"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • နှေးကွေးစွာ အားသွင်းနေသည် • အားပြည့်ရန် <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> လိုသည်"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • အားသွင်းနေသည် • အားပြည့်ရန် <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> လိုသည်"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"အများသုံးရှင်းလင်းပို့ချချက် စတင်ရန် ဘယ်သို့ပွတ်ဆွဲပါ"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 0f73d986dc16..f873274d9f95 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth er tilkoblet."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikon for Bluetooth-enheter"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klikk for å konfigurere enhetsdetaljer"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriprosenten er ukjent."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Koblet til <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Koblet til <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bruk Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Tilkoblet"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Lagret"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Hodetelefoner"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lader raskt • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lader sakte • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Lader • Fulladet om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Sveip til venstre for å starte fellesveiledningen"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Åpne modulvelgeren"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Fjern en modul"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Nylig brukt av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"I bruk av <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">"Nylig brukt av <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index b921f58ee1a3..24d7ffe5372d 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ब्लुटुथ जडान भयो।"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ब्लुटुथ डिभाइस जनाउने आइकन"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"डिभाइसको विवरण कन्फिगर गर्न क्लिक गर्नुहोस्"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ब्याट्रीमा कति प्रतिशत चार्ज छ भन्ने कुराको जानाकरी छैन।"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> मा जडित।"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> मा कनेक्ट गरियो।"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ब्लुटुथ प्रयोग गर्नुहोस्"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"कनेक्ट गरिएको छ"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"सेभ गरिएको छ"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ब्याट्री"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"अडियो"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • बिस्तारै चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा पूरै चार्ज हुन्छ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • चार्ज हुँदै छ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> मा फुल चार्ज हुने छ"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"कम्युनल ट्युटोरियल सुरु गर्न बायाँतिर स्वाइप गर्नुहोस्"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"विजेट पिकर खोल्नुहोस्"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"कुनै विजेट हटाउनुहोस्"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ले हालसालै प्रयोग गरेको"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 9e070153c6d3..9a110a251aba 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-verbinding ingesteld."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icoon voor bluetooth-apparaat"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klik om de apparaatgegevens in te stellen"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batterijpercentage onbekend."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Verbonden met <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Verbonden met <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth gebruiken"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Verbonden"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Opgeslagen"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Langzaam opladen • Vol over <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Opladen • Vol over <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Swipe naar links om de communitytutorial te starten"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Open de widgetkiezer"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Verwijder een widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Recent gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Gebruikt door <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">"Recent gebruikt door <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 62bfdec7adda..a7726277eab9 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"ବ୍ଲୁଟୂଥ୍ ସଂଯୋଗ କରାଯାଇଛି।"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଆଇକନ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ଡିଭାଇସ ବିବରଣୀକୁ କନଫିଗର କରିବା ପାଇଁ କ୍ଲିକ କରନ୍ତୁ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ବ୍ୟାଟେରୀ ଶତକଡ଼ା ଅଜଣା ଅଟେ।"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ସହ ସଂଯୁକ୍ତ"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ସହିତ ସଂଯୁକ୍ତ।"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରନ୍ତୁ"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"କନେକ୍ଟ କରାଯାଇଛି"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ସେଭ କରାଯାଇଛି"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ବ୍ୟାଟେରୀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ଅଡିଓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ହେଡସେଟ୍"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଶୀଘ୍ର ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଧୀରେ ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ଚାର୍ଜ ହେଉଛି • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>ରେ ସମ୍ପୂର୍ଣ୍ଣ ହେବ"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"କମ୍ୟୁନାଲ ଟ୍ୟୁଟୋରିଆଲ ଆରମ୍ଭ କରିବା ପାଇଁ ବାମକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ୱିଜେଟ ପିକର ଖୋଲନ୍ତୁ"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ଏକ ୱିଜେଟକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</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> @@ -413,7 +418,7 @@ <string name="guest_notification_session_active" msgid="5567273684713471450">"ଆପଣ ଅତିଥି ମୋଡରେ ଅଛନ୍ତି"</string> <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ଦ୍ୱାରା ଅତିଥି ମୋଡରୁ ବାହାରି ଯିବ ଏବଂ ବର୍ତ୍ତମାନର ଅତିଥି ସେସନରୁ ସମସ୍ତ ଆପ ଓ ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string> <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string> - <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{କେବଳ ଜଣେ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଇପାରିବ।}other{କେବଳ # ଜଣ ଉପଯୋଗକର୍ତ୍ତା ତିଆରି କରାଯାଇପାରିବ।}}"</string> + <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{କେବଳ ଜଣେ ୟୁଜର ତିଆରି କରାଯାଇପାରିବ।}other{କେବଳ # ଜଣ ୟୁଜର ତିଆରି କରାଯାଇପାରିବ।}}"</string> <string name="user_remove_user_title" msgid="9124124694835811874">"ୟୁଜରଙ୍କୁ ବାହାର କରିବେ?"</string> <string name="user_remove_user_message" msgid="6702834122128031833">"ଏହି ୟୁଜରଙ୍କ ସମସ୍ତ ଆପ୍ ଓ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string> <string name="user_remove_user_remove" msgid="8387386066949061256">"କାଢ଼ି ଦିଅନ୍ତୁ"</string> @@ -509,7 +514,7 @@ <string name="sound_settings" msgid="8874581353127418308">"ସାଉଣ୍ଡ ଓ ଭାଇବ୍ରେସନ"</string> <string name="volume_panel_dialog_settings_button" msgid="2513228491513390310">"ସେଟିଂସ"</string> <string name="csd_lowered_title" product="default" msgid="2464112924151691129">"ଭଲ୍ୟୁମକୁ ସୁରକ୍ଷିତ ଲେଭେଲକୁ କମ କରାଯାଇଛି"</string> - <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ସୁପାରିଶ କରାଯାଇଥିବା ଅପେକ୍ଷା ଅଧିକ ସମୟ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ଅଧିକ ଅଛି"</string> + <string name="csd_system_lowered_text" product="default" msgid="1250251883692996888">"ସୁପାରିଶ ଭଲ୍ୟୁମ ଠାରୁ ହେଡଫୋନର ଭଲ୍ୟୁମ ଅଧିକ ଅଛି"</string> <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"ଏହି ସପ୍ତାହ ପାଇଁ ହେଡଫୋନର ଭଲ୍ୟୁମ ସୁରକ୍ଷିତ ସୀମାକୁ ଅତିକ୍ରମ କରିଛି"</string> <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"ଶୁଣିବା ଜାରି ରଖନ୍ତୁ"</string> <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"ଭଲ୍ୟୁମ କମାନ୍ତୁ"</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"ଏବେ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string> </resources> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index f14962eaf0c3..bb956b6bc0a1 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ਕਨੈਕਟ ਕੀਤੀ।"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ਬਲੂਟੁੱਥ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਤੀਕ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"ਡੀਵਾਈਸ ਦੇ ਵੇਰਵੇ ਦਾ ਸੰਰੂਪਣ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ਬੈਟਰੀ ਪ੍ਰਤੀਸ਼ਤ ਅਗਿਆਤ ਹੈ।"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ।"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ।"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ਬਲੂਟੁੱਥ ਵਰਤੋ"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"ਕਨੈਕਟ ਹੈ"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"ਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ਬੈਟਰੀ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ਆਡੀਓ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ਹੈੱਡਸੈੱਟ"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਤੇਜ਼ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> ਵਿੱਚ ਪੂਰਾ ਚਾਰਜ ਹੋਵੇਗਾ"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"ਭਾਈਚਾਰਕ ਟਿਊਟੋਰੀਅਲ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ਵਿਜੇਟ ਚੋਣਕਾਰ ਨੂੰ ਖੋਲ੍ਹੋ"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ਵਿਜੇਟ ਨੂੰ ਹਟਾਓ"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"ਹਾਲ ਹੀ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ਵੱਲੋਂ ਵਰਤਿਆ ਗਿਆ"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 4be47d458f5e..a28329f74a14 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth połączony."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona urządzenia Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknij, aby skonfigurować szczegóły urządzenia"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Poziom naładowania baterii jest nieznany."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Połączono z <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Połączono z urządzeniem <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Użyj Bluetootha"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Połączone"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Zapisane"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Dźwięk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Zestaw słuchawkowy"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Szybkie ładowanie • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Wolne ładowanie • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Ładowanie • Pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Aby uruchomić wspólny samouczek, przeciągnij palcem w lewo"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 509a3bf807e8..0c0aafa6651e 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ícone de dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Clique para configurar os detalhes do dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Deslize para a esquerda para iniciar o tutorial compartilhado"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Abrir o seletor de widgets"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remover um widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <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">"Usado recentemente pelo app <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 46476c096eb3..0cfc7aaecc81 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ligado."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ícone de dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Clique para configurar o detalhe do dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percentagem da bateria desconhecida."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ligado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Ligado a <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ligado"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Guardado"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ausc. c/ mic. integ."</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • A carregar lentamente • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • A carregar • Carga completa em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Deslize rapidamente para a esquerda para iniciar o tutorial coletivo"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Abrir seletor de widgets"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remover widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Usado recentemente pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em utilização pela app <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">"Usado recentemente pela app <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz do teclado"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 509a3bf807e8..0c0aafa6651e 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth conectado."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ícone de dispositivo Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Clique para configurar os detalhes do dispositivo"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Porcentagem da bateria desconhecida."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectado a <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Conectado a <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvo"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carga lenta • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregando • Conclusão em <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Deslize para a esquerda para iniciar o tutorial compartilhado"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Abrir o seletor de widgets"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Remover um widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <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">"Usado recentemente pelo app <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index c737b5da465f..4df30fa5636b 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Conectat prin Bluetooth."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Pictograma de dispozitiv Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Dă clic pentru a configura detaliile dispozitivului"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Procentajul bateriei este necunoscut."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Conectat la <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"S-a stabilit conexiunea la <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Folosește Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectat"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Salvat"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Căști"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Se încarcă rapid • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Se încarcă lent • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Se încarcă • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> până la încărcarea completă"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Glisează spre stânga pentru a începe tutorialul pentru comunitate"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index bfd005613a9e..c29dc11b5f5b 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth-соединение установлено."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Значок устройства Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Нажмите, чтобы изменить информацию об устройстве"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Уровень заряда батареи в процентах неизвестен."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>: подключено."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Подключено к: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Использовать"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Подключено"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сохранено"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Заряд: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудиоустройство"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Быстрая зарядка • Осталось <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Медленная зарядка • Осталось <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Зарядка • Осталось <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Чтобы ознакомиться с руководством, проведите по экрану влево"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index eb3b8e54e906..68bd1ce3413e 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"බ්ලූටූත් සම්බන්ධිතයි."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"බ්ලූටූත් උපාංග නිරූපකය"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"උපාංග විස්තර වින්යාස කිරීමට ක්ලික් කරන්න"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"බැටරි ප්රතිශතය නොදනී."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> වෙත සම්බන්ධ කරන ලදි."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> වෙත සම්බන්ධ විය."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"බ්ලූටූත් භාවිතා කරන්න"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"සම්බන්ධිතයි"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"සුරැකිණි"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"බැටරිය <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ශ්රව්ය"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"හෙඩ්සෙටය"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • වේගයෙන් ආරෝපණය වෙමින් • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • සෙමින් ආරෝපණය වෙමින් • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • ආරෝපණය වෙමින් • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>කින් සම්පූර්ණ වේ"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"පොදු නිබන්ධනය ආරම්භ කිරීමට වමට ස්වයිප් කරන්න"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 6c4505b3c66b..f916bf272ba3 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth pripojené."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona zariadenia s rozhraním Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknutím nakonfigurujte podrobnosti o zariadení"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Percento batérie nie je známe."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Pripojené k zariadeniu <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Pripojené k zariadeniu <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Použiť Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Pripojené"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Uložené"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Náhlavná súprava"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíja sa rýchlo • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíja sa pomaly • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nabíja sa • Do úplného nabitia zostáva <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Potiahnutím doľava spustite komunitný návod"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index eddb50c0974c..72de807d4c04 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Povezava Bluetooth vzpostavljena."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona naprave Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliknite za konfiguriranje podrobnosti o napravi"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Neznan odstotek napolnjenosti baterije."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Povezava vzpostavljena z: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Vzpostavljena povezava: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Uporabi Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Shranjeno"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvok"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalke z mikrofonom"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hitro polnjenje • Napolnjeno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Počasno polnjenje • Napolnjeno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Polnjenje • Napolnjeno čez <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Povlecite levo, da zaženete vadnico za skupnost"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 984829840e48..2c1f6ac50f66 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Pajisja është lidhur me \"bluetooth\"."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Ikona e pajisjes me Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Kliko për të konfiguruar detajet e pajisjes"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Përqindja e baterisë e panjohur."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Lidhur me <xliff:g id="BLUETOOTH">%s</xliff:g>"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Është lidhur me <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Përdor Bluetooth-in"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Lidhur"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ruajtur"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kufje me mikrofon"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet shpejt • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet ngadalë • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Po karikohet • Plot për <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Rrëshqit shpejt majtas për të filluar udhëzuesin e përbashkët"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 8711abd03f9d..428cc5f71d07 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth је прикључен."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Икона Bluetooth уређаја"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Кликните да бисте конфигурисали детаље о уређају"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Проценат напуњености батерије није познат."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Повезани сте са <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Повезани смо са уређајем <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Користи Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Повезано"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Сачувано"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Ниво батерије је <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудио"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Слушалице"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Брзо се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Споро се пуни • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Пуни се • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до краја пуњења"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Превуците улево да бисте започели заједнички водич"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Отвори бирач виџета"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Уклони виџет"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 9568964c77ce..179ed6e77714 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ansluten."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Enhetsikon för Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Klicka för att konfigurera enhetsinformation"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Okänd batterinivå."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ansluten till <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Ansluten till <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Använd Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ansluten"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Sparad"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ljud"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laddas snabbt • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laddas långsamt • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Laddas • Fulladdat om <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Svep åt vänster för att börja med gruppguiden"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 7535d6805dae..36aa7d56b767 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth imeunganishwa."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Aikoni ya Kifaa chenye Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Bofya ili uweke mipangilio ya maelezo ya kifaa"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Asilimia ya betri haijulikani."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Imeunganishwa kwenye <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Imeunganishwa kwenye <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Tumia Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Imeunganishwa"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Imehifadhiwa"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Sauti"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Vifaa vya sauti"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Inachaji kwa kasi • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Inachaji polepole • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Inachaji • Itajaa baada ya <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Telezesha kidole kushoto ili uanze mafunzo ya pamoja"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Fungua kiteua wijeti"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Ondoa wijeti"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Ilitumiwa hivi majuzi na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Inatumiwa na <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">"Ilitumiwa hivi majuzi na <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 83271906c869..1f3264635589 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"புளூடூத் இணைக்கப்பட்டது."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"புளூடூத் சாதன ஐகான்"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"சாதன விவரத்தை உள்ளமைக்க கிளிக் செய்யலாம்"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"பேட்டரி சதவீதம் தெரியவில்லை."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>க்கு இணைக்கப்பட்டது."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> உடன் இணைக்கப்பட்டுள்ளது."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"புளூடூத்தைப் பயன்படுத்துதல்"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"இணைக்கப்பட்டது"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"சேமிக்கப்பட்டது"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> பேட்டரி"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ஆடியோ"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ஹெட்செட்"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • வேகமாகச் சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுதும் சார்ஜாகும்"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • மெதுவாக சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுதும் சார்ஜாகும்"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • சார்ஜாகிறது • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> இல் முழுவதும் சார்ஜாகும்"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"சமூகப் பயிற்சியைத் தொடங்க இடதுபுறம் ஸ்வைப் செய்யுங்கள்"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index bfa40e8f4f60..e7ba58349d04 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"బ్లూటూత్ కనెక్ట్ చేయబడింది."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"బ్లూటూత్ పరికర చిహ్నం"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"పరికర వివరాలను కాన్ఫిగర్ చేయడానికి క్లిక్ చేయండి"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"బ్యాటరీ శాతం తెలియదు."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g>కి కనెక్ట్ చేయబడింది."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"బ్లూటూత్ వాడండి"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"కనెక్ట్ అయింది"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"సేవ్ చేయబడింది"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> బ్యాటరీ"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ఆడియో"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"హెడ్సెట్"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index f9676745eb6a..1651e540f72a 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"เชื่อมต่อบลูทูธแล้ว"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"ไอคอนอุปกรณ์บลูทูธ"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"คลิกเพื่อกำหนดค่ารายละเอียดอุปกรณ์"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"ไม่ทราบเปอร์เซ็นต์แบตเตอรี่"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"เชื่อมต่อกับ <xliff:g id="BLUETOOTH">%s</xliff:g> แล้ว"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"เชื่อมต่อกับ <xliff:g id="CAST">%s</xliff:g>"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"ใช้บลูทูธ"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"เชื่อมต่อแล้ว"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"บันทึกแล้ว"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"แบตเตอรี่ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"เสียง"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ชุดหูฟัง"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จอย่างเร็ว • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จอย่างช้าๆ • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • กำลังชาร์จ • จะเต็มในอีก <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"ปัดไปทางซ้ายเพื่อเริ่มบทแนะนำส่วนกลาง"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"เปิดเครื่องมือเลือกวิดเจ็ต"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"นำวิดเจ็ตออก"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"ใช้ล่าสุดโดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 56565e6ace36..085fdeed18ab 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Nakakonekta ang Bluetooth."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Icon ng Bluetooth device"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"I-click para i-configure ang detalye ng device"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Hindi alam ang porsyento ng baterya."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Nakakonekta sa <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Nakakonekta sa <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gumamit ng Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Nakakonekta"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Na-save"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mabilis na nagcha-charge • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> na lang para mapuno"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Mabagal na nagcha-charge • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> na lang para mapuno"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Nagcha-charge • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> na lang para mapuno"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Mag-swipe pakaliwa para simulan ang communal na tutorial"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Buksan ang picker ng widget"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Mag-alis ng widget"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Kamakailang ginamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Ginagamit ng <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">"Kamakailang ginamit ng <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 89c400122440..820ccd17f4d4 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth bağlandı."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth cihaz simgesi"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Cihaz ayrıntılarını yapılandırmak için tıklayın"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Pil yüzdesi bilinmiyor."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> ile bağlı."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> bağlantısı kuruldu."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth\'u kullan"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Bağlandı"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Kaydedildi"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ses"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Mikrofonlu kulaklık"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Hızlı şarj oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Yavaş şarj oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Şarj oluyor • Dolmasına <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> kaldı"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ortak eğitimi başlatmak için sola kaydırın"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index a83d8bb06b4f..ea3d0b1ed597 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth під’єднано."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Значок пристрою з Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Натисніть, щоб змінити налаштування пристрою"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Відсоток заряду акумулятора невідомий."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Підключено до <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Під’єднано до пристрою <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Увімкнути Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Підключено"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Збережено"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> заряду акумулятора"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Аудіопристрій"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнітура"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Швидке заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Повільне заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Заряджання • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> до повного заряду"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Проведіть пальцем уліво, щоб відкрити спільний навчальний посібник"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index 7a41e9f6e37f..bf58d9c28fd4 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"بلوٹوتھ مربوط ہے۔"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"بلوٹوتھ آلے کا آئیکن"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"آلہ کی تفصیل کو کنفیگر کرنے کے لیے کلک کریں"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"بیٹری کی فیصد نامعلوم ہے۔"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> سے منسلک ہیں۔"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> سے منسلک ہے۔"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"استعمال کریں"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"منسلک ہے"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ ہے"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> بیٹری"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"آڈیو"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"ہیڈ سیٹ"</string> @@ -397,10 +405,8 @@ <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • آہستہ چارج ہو رہا ہے • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> میں مکمل"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • چارج ہو رہا ہے • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> میں مکمل"</string> <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"کمیونل ٹیوٹوریل شروع کرنے کے لیے بائیں سوائپ کریں"</string> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"ویجیٹ چنندہ کو کھولیں"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"ویجیٹ ہٹائیں"</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> @@ -1209,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) کے ذریعے حال ہی میں استعمال کیا گیا"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d میں سے %1$d کا لیول"</string> </resources> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index d01ed196f3af..0e04cd5fd191 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ulandi."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Bluetooth qurilma belgisi"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Qurilma haqida tafsilotlarni oʻzgartirish uchun bosing"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batareya quvvati foizi nomaʼlum."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Ulangan: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Bunga ulangan: <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth ishlatish"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ulandi"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saqlangan"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Garnitura"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Tez quvvat olmoqda • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Sekin quvvat olmoqda • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Quvvat olmoqda • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> qoldi"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Qoʻllanma bilan tanishish uchun chapga suring"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"Vidjet tanlash vositasini ochish"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"Vidjetni olib tashlash"</string> <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string> <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string> <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"Yaqinda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>) ishlatgan"</string> <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>) ishlatmoqda"</string> <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Yaqinda <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>) ishlatgan"</string> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 5a1007693a9d..31350be4091b 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Đã kết nối bluetooth."</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Biểu tượng thiết bị Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Nhấp để định cấu hình thông tin thiết bị"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Tỷ lệ phần trăm pin không xác định."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Đã kết nối với <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Đã kết nối với <xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bật Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Đã kết nối"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Đã lưu"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Âm thanh"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Tai nghe"</string> @@ -396,8 +404,7 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đang sạc nhanh • Sẽ đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đang sạc chậm • Sẽ đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Đang sạc • Sẽ đầy sau <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Vuốt sang trái để bắt đầu xem hướng dẫn chung"</string> <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> <skip /> <!-- no translation found for button_to_remove_widget (1511255853677835341) --> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 92dac523abe9..4db1a91b1ba7 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"蓝牙已连接。"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"蓝牙设备图标"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"点击以配置设备详情"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"电池电量百分比未知。"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已连接到<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"已连接到 <xliff:g id="CAST">%s</xliff:g>。"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"使用蓝牙"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已连接"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已保存"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> 的电量"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音频"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳机"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在快速充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在慢速充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 正在充电 • 将于 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>后充满"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"向左滑动即可启动公共教程"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"打开微件选择器"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"移除微件"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”最近使用过(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index c94c2cb52810..125cfe15164a 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"藍牙連線已建立。"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"藍牙裝置圖示"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"按一下即可設定裝置詳情"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電量百分比不明。"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"已連接至 <xliff:g id="CAST">%s</xliff:g>。"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"使用藍牙"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已連接"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 快速充電中 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 慢速充電中 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 充電中 • <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充滿電"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"向左滑動即可開始共用教學課程"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"開啟小工具挑選器"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"移除小工具"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近使用過此權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index e05d30991f36..dba68c500dc0 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"藍牙連線已建立。"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"「藍牙裝置」圖示"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"按一下即可設定裝置詳細資料"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"電池電量不明。"</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"已連線至<xliff:g id="BLUETOOTH">%s</xliff:g>。"</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"已連線至 <xliff:g id="CAST">%s</xliff:g>。"</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"使用藍牙"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"已連線"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"已儲存"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"電量:<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"音訊"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"耳機"</string> @@ -396,12 +404,9 @@ <string name="keyguard_indication_charging_time_fast" msgid="8390311020603859480">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 快速充電中 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string> <string name="keyguard_indication_charging_time_slowly" msgid="301936949731705417">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 慢速充電中 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string> <string name="keyguard_indication_charging_time_dock" msgid="3149328898931741271">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • 充電中 • 將於 <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>後充飽"</string> - <!-- no translation found for communal_tutorial_indicator_text (4503010353591430123) --> - <skip /> - <!-- no translation found for button_to_open_widget_picker (8007261659745030810) --> - <skip /> - <!-- no translation found for button_to_remove_widget (1511255853677835341) --> - <skip /> + <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"向左滑動即可啟動通用教學課程"</string> + <string name="button_to_open_widget_picker" msgid="8007261659745030810">"開啟小工具挑選器"</string> + <string name="button_to_remove_widget" msgid="1511255853677835341">"移除小工具"</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> @@ -1210,8 +1215,6 @@ <string name="privacy_dialog_recent_app_usage_1" msgid="2551340497722370109">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近用過這項權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>)"</string> <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> - <!-- no translation found for keyboard_backlight_dialog_title (8273102932345564724) --> - <skip /> - <!-- no translation found for keyboard_backlight_value (7336398765584393538) --> - <skip /> + <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string> + <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index db2ba79b3e5d..982ca4a12dd8 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -197,6 +197,10 @@ <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth ixhunyiwe"</string> <string name="accessibility_bluetooth_device_icon" msgid="9163840051642587982">"Isithonjana sedivayisi ye-Bluetooth"</string> <string name="accessibility_bluetooth_device_settings_gear" msgid="3314916468105272540">"Chofoza ukuze ulungiselele imininingwane yedivayisi"</string> + <!-- no translation found for accessibility_bluetooth_device_settings_see_all (9111952496905423543) --> + <skip /> + <!-- no translation found for accessibility_bluetooth_device_settings_pair_new_device (2435184865793496966) --> + <skip /> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Iphesenti lebhethri alaziwa."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Xhuma ku-<xliff:g id="BLUETOOTH">%s</xliff:g>."</string> <string name="accessibility_cast_name" msgid="7344437925388773685">"Ixhumeke ku-<xliff:g id="CAST">%s</xliff:g>."</string> @@ -255,6 +259,10 @@ <string name="turn_on_bluetooth" msgid="5681370462180289071">"Sebenzisa i-Bluetooth"</string> <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Ixhunyiwe"</string> <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Ilondoloziwe"</string> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_disconnect (415980329093277342) --> + <skip /> + <!-- no translation found for accessibility_quick_settings_bluetooth_device_tap_to_activate (3724301751036877403) --> + <skip /> <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string> <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Umsindo"</string> <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ihedisethi"</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 2117714a4df1..befee2b3eeb7 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -1496,10 +1496,14 @@ <style name="ShortCutButton" parent="@android:style/Widget.Material.Button"> <item name="android:background">@drawable/shortcut_button_colored</item> - <item name="android:stateListAnimator">@null</item> <item name="android:textSize">16sp</item> - <item name="android:padding">4dp</item> - <item name="android:textColor">?androidprv:attr/textColorSecondary</item> + <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item> + <item name="android:layout_marginEnd">12dp</item> + <item name="android:paddingLeft">24dp</item> + <item name="android:paddingRight">24dp</item> + <item name="android:minHeight">40dp</item> + <item name="android:stateListAnimator">@*android:anim/flat_button_state_list_anim_material</item> + <item name="android:pointerIcon">arrow</item> </style> <style name="ShortcutHorizontalDivider"> @@ -1535,4 +1539,4 @@ <style name="Theme.PrivacyDialog" parent="@style/Theme.SystemUI.Dialog"> <item name="android:colorBackground">?androidprv:attr/materialColorSurfaceContainer</item> </style> -</resources>
\ No newline at end of file +</resources> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index dedac5596817..1fa55f5d839b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -39,6 +39,7 @@ import androidx.annotation.VisibleForTesting; import com.android.systemui.Dumpable; import com.android.systemui.common.ui.ConfigurationState; +import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlagsClassic; @@ -78,6 +79,7 @@ import com.android.systemui.util.settings.SecureSettings; import java.io.PrintWriter; import java.util.Locale; +import java.util.concurrent.Executor; import java.util.function.Consumer; import javax.inject.Inject; @@ -136,6 +138,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private KeyguardInteractor mKeyguardInteractor; private KeyguardClockInteractor mKeyguardClockInteractor; private final DelayableExecutor mUiExecutor; + private final Executor mBgExecutor; private boolean mCanShowDoubleLineClock = true; private DisposableHandle mAodIconsBindHandle; @Nullable private NotificationIconContainer mAodIconContainer; @@ -186,6 +189,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS KeyguardUnlockAnimationController keyguardUnlockAnimationController, SecureSettings secureSettings, @Main DelayableExecutor uiExecutor, + @Background Executor bgExecutor, DumpManager dumpManager, ClockEventController clockEventController, @KeyguardClockLog LogBuffer logBuffer, @@ -209,6 +213,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mIconViewBindingFailureTracker = iconViewBindingFailureTracker; mSecureSettings = secureSettings; mUiExecutor = uiExecutor; + mBgExecutor = bgExecutor; mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; mDumpManager = dumpManager; mClockEventController = clockEventController; @@ -328,19 +333,22 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS updateAodIcons(); mStatusArea = mView.findViewById(R.id.keyguard_status_area); - mSecureSettings.registerContentObserverForUser( - Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, - false, /* notifyForDescendants */ - mDoubleLineClockObserver, - UserHandle.USER_ALL - ); - - mSecureSettings.registerContentObserverForUser( - Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED, - false, /* notifyForDescendants */ - mShowWeatherObserver, - UserHandle.USER_ALL - ); + mBgExecutor.execute(() -> { + mSecureSettings.registerContentObserverForUser( + Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, + false, /* notifyForDescendants */ + mDoubleLineClockObserver, + UserHandle.USER_ALL + ); + + mSecureSettings.registerContentObserverForUser( + Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED, + false, /* notifyForDescendants */ + mShowWeatherObserver, + UserHandle.USER_ALL + ); + }); + updateDoubleLineClock(); mKeyguardUnlockAnimationController.addKeyguardUnlockAnimationListener( @@ -382,8 +390,10 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mClockEventController.unregisterListeners(); setClock(null); - mSecureSettings.unregisterContentObserver(mDoubleLineClockObserver); - mSecureSettings.unregisterContentObserver(mShowWeatherObserver); + mBgExecutor.execute(() -> { + mSecureSettings.unregisterContentObserver(mDoubleLineClockObserver); + mSecureSettings.unregisterContentObserver(mShowWeatherObserver); + }); mKeyguardUnlockAnimationController.removeKeyguardUnlockAnimationListener( mKeyguardUnlockAnimationListener); diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 07359d1b446c..175fcdb6e11a 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -26,7 +26,7 @@ import static com.android.systemui.Flags.keyguardBottomAreaRefactor; import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1; import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; -import static com.android.systemui.flags.Flags.NEW_AOD_TRANSITION; +import static com.android.systemui.Flags.newAodTransition; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import android.annotation.SuppressLint; @@ -395,7 +395,7 @@ public class LockIconViewController implements Dumpable { mView.updateIcon(ICON_LOCK, true); mView.setContentDescription(mLockedLabel); mView.setVisibility(View.VISIBLE); - } else if (mIsDozing && mFeatureFlags.isEnabled(NEW_AOD_TRANSITION)) { + } else if (mIsDozing && newAodTransition()) { mView.animate() .alpha(0f) .setDuration(FADE_OUT_DURATION_MS) diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt index f94f8c594aa6..634531215002 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt @@ -31,11 +31,11 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.keyguard.logging.KeyguardLogger import com.android.settingslib.Utils import com.android.systemui.CoreStartable +import com.android.systemui.Flags.lightRevealMigration import com.android.systemui.res.R import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.log.core.LogLevel import com.android.systemui.plugins.statusbar.StatusBarStateController @@ -191,7 +191,7 @@ class AuthRippleController @Inject constructor( // This code path is not used if the KeyguardTransitionRepository is managing the light // reveal scrim. - if (!featureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (!lightRevealMigration()) { if (statusBarStateController.isDozing || biometricUnlockController.isWakeAndUnlock) { circleReveal?.let { lightRevealScrim.revealAmount = 0f @@ -210,7 +210,7 @@ class AuthRippleController @Inject constructor( } override fun onKeyguardFadingAwayChanged() { - if (featureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (lightRevealMigration()) { return } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt index 8f61dbfbdd10..91cee9e51a93 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt @@ -62,6 +62,7 @@ import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.dump.DumpManager import com.android.systemui.res.R import com.android.systemui.util.boundsOnScreen @@ -190,7 +191,10 @@ constructor( } private fun listenForAlternateBouncerVisibility() { - alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, "SideFpsController") + if (!DeviceEntryUdfpsRefactor.isEnabled) { + alternateBouncerInteractor.setAlternateBouncerUIAvailable(true, "SideFpsController") + } + scope.launch { alternateBouncerInteractor.isVisible.collect { isVisible: Boolean -> if (isVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt index c0b21534c5f3..1e0e16c5472f 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/data/repository/KeyguardBouncerRepository.kt @@ -22,6 +22,7 @@ import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EX import com.android.systemui.bouncer.shared.model.BouncerShowMessageModel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.log.dagger.BouncerTableLog import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable @@ -208,6 +209,7 @@ constructor( } override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) { + DeviceEntryUdfpsRefactor.assertInLegacyMode() _alternateBouncerUIAvailable.value = isAvailable } diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt index 9a7fec1daae0..a7211007e5e3 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt @@ -17,14 +17,23 @@ package com.android.systemui.bouncer.domain.interactor import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository +import com.android.systemui.biometrics.shared.model.FingerprintSensorType import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.time.SystemClock import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn /** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */ @SysUISingleton @@ -34,13 +43,29 @@ constructor( private val statusBarStateController: StatusBarStateController, private val keyguardStateController: KeyguardStateController, private val bouncerRepository: KeyguardBouncerRepository, + fingerprintPropertyRepository: FingerprintPropertyRepository, private val biometricSettingsRepository: BiometricSettingsRepository, private val systemClock: SystemClock, private val keyguardUpdateMonitor: KeyguardUpdateMonitor, + @Application scope: CoroutineScope, ) { var receivedDownTouch = false val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible private val alternateBouncerUiAvailableFromSource: HashSet<String> = HashSet() + private val alternateBouncerSupported: StateFlow<Boolean> = + if (DeviceEntryUdfpsRefactor.isEnabled) { + fingerprintPropertyRepository.sensorType + .map { sensorType -> + sensorType.isUdfps() || sensorType == FingerprintSensorType.POWER_BUTTON + } + .stateIn( + scope = scope, + started = SharingStarted.Eagerly, + initialValue = false, + ) + } else { + bouncerRepository.alternateBouncerUIAvailable + } /** * Sets the correct bouncer states to show the alternate bouncer if it can show. @@ -71,6 +96,7 @@ constructor( } fun setAlternateBouncerUIAvailable(isAvailable: Boolean, token: String) { + DeviceEntryUdfpsRefactor.assertInLegacyMode() if (isAvailable) { alternateBouncerUiAvailableFromSource.add(token) } else { @@ -82,7 +108,7 @@ constructor( } fun canShowAlternateBouncerForFingerprint(): Boolean { - return bouncerRepository.alternateBouncerUIAvailable.value && + return alternateBouncerSupported.value && biometricSettingsRepository.isFingerprintAuthCurrentlyAllowed.value && !keyguardUpdateMonitor.isFingerprintLockedOut && !keyguardStateController.isUnlocked && diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt index d5ac48371ae9..b598631c3b57 100644 --- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt @@ -26,6 +26,7 @@ import com.android.systemui.classifier.FalsingClassifier import com.android.systemui.classifier.domain.interactor.FalsingInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R import com.android.systemui.scene.shared.flag.SceneContainerFlags @@ -51,6 +52,7 @@ constructor( @Application private val applicationContext: Context, private val repository: BouncerRepository, private val authenticationInteractor: AuthenticationInteractor, + private val keyguardFaceAuthInteractor: KeyguardFaceAuthInteractor, flags: SceneContainerFlags, private val falsingInteractor: FalsingInteractor, private val powerInteractor: PowerInteractor, @@ -131,6 +133,7 @@ constructor( * user's pocket or by the user's face while holding their device up to their ear. */ fun onIntentionalUserInput() { + keyguardFaceAuthInteractor.onPrimaryBouncerUserInput() powerInteractor.onUserTouch() falsingInteractor.updateFalseConfidence(FalsingClassifier.Result.passed(0.6)) } diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt index 48d374207388..48d3fe000ff8 100644 --- a/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt +++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/SharedNotificationContainerPosition.kt @@ -23,4 +23,6 @@ data class SharedNotificationContainerPosition( /** Whether any modifications to top/bottom are smoothly animated */ val animate: Boolean = false, -) +) { + val height: Float = bottom - top +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt index 7391a5e8e5fc..927bf024215d 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt @@ -32,7 +32,6 @@ import javax.inject.Inject import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map @@ -47,7 +46,6 @@ constructor( private val widgetRepository: CommunalWidgetRepository, mediaRepository: CommunalMediaRepository, smartspaceRepository: SmartspaceRepository, - tutorialInteractor: CommunalTutorialInteractor, private val appWidgetHost: AppWidgetHost, private val editWidgetsActivityStarter: EditWidgetsActivityStarter ) { @@ -86,20 +84,8 @@ constructor( /** Delete a widget by id. */ fun deleteWidget(id: Int) = widgetRepository.deleteWidget(id) - /** A list of all the communal content to be displayed in the communal hub. */ - @OptIn(ExperimentalCoroutinesApi::class) - val communalContent: Flow<List<CommunalContentModel>> = - tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode -> - if (isTutorialMode) { - return@flatMapLatest flowOf(tutorialContent) - } - combine(smartspaceContent, umoContent, widgetContent) { smartspace, umo, widgets -> - smartspace + umo + widgets - } - } - /** A list of widget content to be displayed in the communal hub. */ - private val widgetContent: Flow<List<CommunalContentModel.Widget>> = + val widgetContent: Flow<List<CommunalContentModel.Widget>> = widgetRepository.communalWidgets.map { widgets -> widgets.map Widget@{ widget -> return@Widget CommunalContentModel.Widget( @@ -111,7 +97,7 @@ constructor( } /** A flow of available smartspace content. Currently only showing timer targets. */ - private val smartspaceContent: Flow<List<CommunalContentModel.Smartspace>> = + val smartspaceContent: Flow<List<CommunalContentModel.Smartspace>> = if (!smartspaceRepository.isSmartspaceRemoteViewsEnabled) { flowOf(emptyList()) } else { @@ -133,7 +119,7 @@ constructor( } /** A list of tutorial content to be displayed in the communal hub in tutorial mode. */ - private val tutorialContent: List<CommunalContentModel.Tutorial> = + val tutorialContent: List<CommunalContentModel.Tutorial> = listOf( CommunalContentModel.Tutorial(id = 0, CommunalContentSize.FULL), CommunalContentModel.Tutorial(id = 1, CommunalContentSize.THIRD), @@ -145,7 +131,7 @@ constructor( CommunalContentModel.Tutorial(id = 7, CommunalContentSize.HALF), ) - private val umoContent: Flow<List<CommunalContentModel.Umo>> = + val umoContent: Flow<List<CommunalContentModel.Umo>> = mediaRepository.mediaPlaying.flatMapLatest { mediaPlaying -> if (mediaPlaying) { // TODO(b/310254801): support HALF and FULL layouts diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt new file mode 100644 index 000000000000..98f3594801f3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.ui.viewmodel + +import com.android.systemui.communal.domain.interactor.CommunalInteractor +import com.android.systemui.communal.domain.model.CommunalContentModel +import com.android.systemui.communal.shared.model.CommunalSceneKey +import com.android.systemui.media.controls.ui.MediaHost +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow + +/** The base view model for the communal hub. */ +abstract class BaseCommunalViewModel( + private val communalInteractor: CommunalInteractor, + val mediaHost: MediaHost, +) { + val currentScene: StateFlow<CommunalSceneKey> = communalInteractor.desiredScene + + fun onSceneChanged(scene: CommunalSceneKey) { + communalInteractor.onSceneChanged(scene) + } + + /** A list of all the communal content to be displayed in the communal hub. */ + abstract val communalContent: Flow<List<CommunalContentModel>> + + /** Whether in edit mode for the communal hub. */ + open val isEditMode = false + + /** Called as the UI requests deleting a widget. */ + open fun onDeleteWidget(id: Int) {} + + /** Called as the UI requests opening the widget editor. */ + open fun onOpenWidgetEditor() {} +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt new file mode 100644 index 000000000000..14d9b2ca80f0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.ui.viewmodel + +import com.android.systemui.communal.domain.interactor.CommunalInteractor +import com.android.systemui.communal.domain.model.CommunalContentModel +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.media.controls.ui.MediaHost +import com.android.systemui.media.dagger.MediaModule +import javax.inject.Inject +import javax.inject.Named +import kotlinx.coroutines.flow.Flow + +/** The view model for communal hub in edit mode. */ +@SysUISingleton +class CommunalEditModeViewModel +@Inject +constructor( + private val communalInteractor: CommunalInteractor, + @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, +) : BaseCommunalViewModel(communalInteractor, mediaHost) { + + override val isEditMode = true + + // Only widgets are editable. + override val communalContent: Flow<List<CommunalContentModel>> = + communalInteractor.widgetContent + + override fun onDeleteWidget(id: Int) = communalInteractor.deleteWidget(id) +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt index 14edc8e0a88c..eaf2d5741e23 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt @@ -17,34 +17,43 @@ package com.android.systemui.communal.ui.viewmodel import com.android.systemui.communal.domain.interactor.CommunalInteractor +import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor import com.android.systemui.communal.domain.model.CommunalContentModel -import com.android.systemui.communal.shared.model.CommunalSceneKey import com.android.systemui.dagger.SysUISingleton import com.android.systemui.media.controls.ui.MediaHost import com.android.systemui.media.dagger.MediaModule import javax.inject.Inject import javax.inject.Named +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf +/** The default view model used for showing the communal hub. */ @SysUISingleton class CommunalViewModel @Inject constructor( private val communalInteractor: CommunalInteractor, - @Named(MediaModule.COMMUNAL_HUB) val mediaHost: MediaHost, -) { - val currentScene: StateFlow<CommunalSceneKey> = communalInteractor.desiredScene - fun onSceneChanged(scene: CommunalSceneKey) { - communalInteractor.onSceneChanged(scene) - } + tutorialInteractor: CommunalTutorialInteractor, + @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost, +) : BaseCommunalViewModel(communalInteractor, mediaHost) { - /** A list of all the communal content to be displayed in the communal hub. */ - val communalContent: Flow<List<CommunalContentModel>> = communalInteractor.communalContent + @OptIn(ExperimentalCoroutinesApi::class) + override val communalContent: Flow<List<CommunalContentModel>> = + tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode -> + if (isTutorialMode) { + return@flatMapLatest flowOf(communalInteractor.tutorialContent) + } + combine( + communalInteractor.smartspaceContent, + communalInteractor.umoContent, + communalInteractor.widgetContent, + ) { smartspace, umo, widgets -> + smartspace + umo + widgets + } + } - /** Delete a widget by id. */ - fun onDeleteWidget(id: Int) = communalInteractor.deleteWidget(id) - - /** Open the widget editor */ - fun onOpenWidgetEditor() = communalInteractor.showWidgetEditor() + override fun onOpenWidgetEditor() = communalInteractor.showWidgetEditor() } diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt index 78e85db9ea05..7b94fc182fe2 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt @@ -20,17 +20,21 @@ import android.appwidget.AppWidgetProviderInfo import android.content.Intent import android.os.Bundle import android.util.Log -import android.view.View import androidx.activity.ComponentActivity import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import com.android.systemui.communal.domain.interactor.CommunalInteractor -import com.android.systemui.res.R +import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel +import com.android.systemui.compose.ComposeFacade.setCommunalEditWidgetActivityContent import javax.inject.Inject /** An Activity for editing the widgets that appear in hub mode. */ -class EditWidgetsActivity @Inject constructor(private val communalInteractor: CommunalInteractor) : - ComponentActivity() { +class EditWidgetsActivity +@Inject +constructor( + private val communalViewModel: CommunalEditModeViewModel, + private val communalInteractor: CommunalInteractor, +) : ComponentActivity() { companion object { /** * Intent extra name for the {@link AppWidgetProviderInfo} of a widget to add to hub mode. @@ -59,20 +63,19 @@ class EditWidgetsActivity @Inject constructor(private val communalInteractor: Co "Failed to receive result from widget picker, code=${result.resultCode}" ) } - this@EditWidgetsActivity.finish() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setShowWhenLocked(true) - setContentView(R.layout.edit_widgets) - - val addWidgetsButton = findViewById<View>(R.id.add_widget) - addWidgetsButton?.setOnClickListener({ - addWidgetActivityLauncher.launch( - Intent(applicationContext, WidgetPickerActivity::class.java) - ) - }) + setCommunalEditWidgetActivityContent( + activity = this, + viewModel = communalViewModel, + onOpenWidgetPicker = { + addWidgetActivityLauncher.launch( + Intent(applicationContext, WidgetPickerActivity::class.java) + ) + }, + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt index 3e6dbd5a7115..a2765486bf2d 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetPickerActivity.kt @@ -43,7 +43,6 @@ constructor( super.onCreate(savedInstanceState) setContentView(R.layout.widget_picker) - setShowWhenLocked(true) loadWidgets() } diff --git a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt index 4bdea75d9d71..65d44957222a 100644 --- a/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt +++ b/packages/SystemUI/src/com/android/systemui/compose/BaseComposeFacade.kt @@ -22,7 +22,7 @@ import android.view.View import android.view.WindowInsets import androidx.activity.ComponentActivity import androidx.lifecycle.LifecycleOwner -import com.android.systemui.communal.ui.viewmodel.CommunalViewModel +import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.people.ui.viewmodel.PeopleViewModel import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel import com.android.systemui.scene.shared.model.Scene @@ -58,6 +58,13 @@ interface BaseComposeFacade { onResult: (PeopleViewModel.Result) -> Unit, ) + /** Bind the content of [activity] to [viewModel]. */ + fun setCommunalEditWidgetActivityContent( + activity: ComponentActivity, + viewModel: BaseCommunalViewModel, + onOpenWidgetPicker: () -> Unit, + ) + /** Create a [View] to represent [viewModel] on screen. */ fun createFooterActionsView( context: Context, @@ -77,9 +84,9 @@ interface BaseComposeFacade { /** Create a [View] to represent [viewModel] on screen. */ fun createCommunalView( context: Context, - viewModel: CommunalViewModel, + viewModel: BaseCommunalViewModel, ): View /** Creates a container that hosts the communal UI and handles gesture transitions. */ - fun createCommunalContainer(context: Context, viewModel: CommunalViewModel): View + fun createCommunalContainer(context: Context, viewModel: BaseCommunalViewModel): View } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index a0e944b0ad71..d041acb4601a 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -37,7 +37,6 @@ import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable import com.android.systemui.keyguard.KeyguardViewConfigurator import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable -import com.android.systemui.keyguard.ui.binder.AlternateBouncerBinder import com.android.systemui.keyguard.ui.binder.KeyguardDismissActionBinder import com.android.systemui.keyguard.ui.binder.KeyguardDismissBinder import com.android.systemui.log.SessionTracker @@ -92,11 +91,6 @@ abstract class SystemUICoreStartableModule { @ClassKey(AuthController::class) abstract fun bindAuthController(service: AuthController): CoreStartable - @Binds - @IntoMap - @ClassKey(AlternateBouncerBinder::class) - abstract fun bindAlternateBouncerBinder(impl: AlternateBouncerBinder): CoreStartable - /** Inject into BiometricNotificationService */ @Binds @IntoMap diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 5f54a98fe05d..482832b03a72 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -106,8 +106,6 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper; import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.people.PeopleHubModule; import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; @@ -374,11 +372,4 @@ public abstract class SystemUIModule { @Binds abstract LargeScreenShadeInterpolator largeScreensShadeInterpolator( LargeScreenShadeInterpolatorImpl impl); - - @SysUISingleton - @Provides - static VisualInterruptionDecisionProvider provideVisualInterruptionDecisionProvider( - NotificationInterruptStateProvider innerProvider) { - return new NotificationInterruptStateProviderWrapper(innerProvider); - } } diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 093319f6434e..7d541070f146 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -148,18 +148,6 @@ object Flags { // TODO(b/255607168): Tracking Bug @JvmField val DOZING_MIGRATION_1 = unreleasedFlag("dozing_migration_1") - /** - * Migrates control of the LightRevealScrim's reveal effect and amount from legacy code to the - * new KeyguardTransitionRepository. - */ - // TODO(b/281655028): Tracking bug - @JvmField - val LIGHT_REVEAL_MIGRATION = unreleasedFlag("light_reveal_migration", teamfood = true) - - // TODO(b/301915812): Tracking Bug - @JvmField - val NEW_AOD_TRANSITION = unreleasedFlag("new_aod_transition", teamfood = true) - // TODO(b/305984787): @JvmField val REFACTOR_GETCURRENTUSER = unreleasedFlag("refactor_getcurrentuser", teamfood = true) @@ -338,6 +326,10 @@ object Flags { // TODO(b/301610137): Tracking bug @JvmField val NEW_NETWORK_SLICE_UI = releasedFlag("new_network_slice_ui") + // TODO(b/311222557): Tracking bug + val ROAMING_INDICATOR_VIA_DISPLAY_INFO = + releasedFlag("roaming_indicator_via_display_info") + // TODO(b/308138154): Tracking bug val FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS = releasedFlag("filter_provisioning_network_subscriptions") diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 4e6a872cb3f7..fe9865b2d1dd 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2720,9 +2720,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, private void updateActivityLockScreenState(boolean showing, boolean aodShowing) { mUiBgExecutor.execute(() -> { - if (DEBUG) { - Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")"); - } + Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")"); if (mFeatureFlags.isEnabled(Flags.KEYGUARD_WM_STATE_REFACTOR)) { // Handled in WmLockscreenVisibilityManager if flag is enabled. @@ -3251,10 +3249,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, DejankUtils.postAfterTraversal(() -> { if (!mPM.isInteractive() && !mPendingLock) { Log.e(TAG, "exitKeyguardAndFinishSurfaceBehindRemoteAnimation#postAfterTraversal:" - + "mPM.isInteractive()=" + mPM.isInteractive() - + "mPendingLock=" + mPendingLock + "." - + "One of these being false means we re-locked the device during unlock. " - + "Do not proceed to finish keyguard exit and unlock."); + + " mPM.isInteractive()=" + mPM.isInteractive() + + " mPendingLock=" + mPendingLock + "." + + " One of these being false means we re-locked the device during unlock." + + " Do not proceed to finish keyguard exit and unlock."); doKeyguardLocked(null); finishSurfaceBehindRemoteAnimation(true /* showKeyguard */); // Ensure WM is notified that we made a decision to show diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index e256b49be8f8..949c940bdebc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -56,6 +56,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -83,10 +84,18 @@ constructor( shadeRepository: ShadeRepository, sceneInteractorProvider: Provider<SceneInteractor>, ) { - /** Position information for the shared notification container. */ - val sharedNotificationContainerPosition = + // TODO(b/296118689): move to a repository + private val _sharedNotificationContainerPosition = MutableStateFlow(SharedNotificationContainerPosition()) + /** Position information for the shared notification container. */ + val sharedNotificationContainerPosition: StateFlow<SharedNotificationContainerPosition> = + _sharedNotificationContainerPosition.asStateFlow() + + fun setSharedNotificationContainerPosition(position: SharedNotificationContainerPosition) { + _sharedNotificationContainerPosition.value = position + } + /** * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at * all. diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt index cb5813e1d4cb..a6383eb5f785 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt @@ -20,45 +20,16 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.CoreStartable -import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import com.android.systemui.scrim.ScrimView -import com.android.systemui.shade.NotificationShadeWindowView import com.android.systemui.statusbar.NotificationShadeWindowController -import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch -@ExperimentalCoroutinesApi -@SysUISingleton -class AlternateBouncerBinder -@Inject -constructor( - private val notificationShadeWindowView: NotificationShadeWindowView, - private val alternateBouncerViewModel: AlternateBouncerViewModel, - @Application private val scope: CoroutineScope, - private val notificationShadeWindowController: NotificationShadeWindowController, -) : CoreStartable { - override fun start() { - if (!DeviceEntryUdfpsRefactor.isEnabled) { - return - } - - AlternateBouncerViewBinder.bind( - notificationShadeWindowView.requireViewById(R.id.alternate_bouncer), - alternateBouncerViewModel, - scope, - notificationShadeWindowController, - ) - } -} - /** * Binds the alternate bouncer view to its view-model. * diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt index c5a8375f5576..eee5206498e4 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt @@ -17,13 +17,11 @@ package com.android.systemui.keyguard.ui.binder import android.annotation.SuppressLint -import android.content.Intent import android.graphics.Rect import android.graphics.drawable.Animatable2 import android.util.Size import android.view.View import android.view.ViewGroup -import android.view.ViewPropertyAnimator import android.widget.ImageView import androidx.core.animation.CycleInterpolator import androidx.core.animation.ObjectAnimator @@ -34,7 +32,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.settingslib.Utils -import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.Expandable import com.android.systemui.animation.view.LaunchableLinearLayout @@ -43,9 +40,12 @@ import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.common.ui.binder.TextViewBinder import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordanceViewModel +import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils +import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils.LAUNCH_SOURCE_KEYGUARD import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.FalsingManager +import com.android.systemui.res.R import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.util.doOnEnd import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -79,7 +79,7 @@ object KeyguardBottomAreaViewBinder { * Users of the [KeyguardBottomAreaViewBinder] class should use this to control the binder after * it is bound. */ - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] @Deprecated("Deprecated as part of b/278057014") interface Binding { /** Notifies that device configuration has changed. */ @@ -133,8 +133,7 @@ object KeyguardBottomAreaViewBinder { val disposableHandle = view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { - - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] launch { viewModel.startButton.collect { buttonModel -> updateButton( @@ -147,7 +146,7 @@ object KeyguardBottomAreaViewBinder { } } - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] launch { viewModel.endButton.collect { buttonModel -> updateButton( @@ -185,7 +184,7 @@ object KeyguardBottomAreaViewBinder { } } - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] launch { updateButtonAlpha( view = startButton, @@ -194,7 +193,7 @@ object KeyguardBottomAreaViewBinder { ) } - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] launch { updateButtonAlpha( view = endButton, @@ -220,7 +219,7 @@ object KeyguardBottomAreaViewBinder { } } - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] launch { configurationBasedDimensions.collect { dimensions -> startButton.updateLayoutParams<ViewGroup.LayoutParams> { @@ -378,13 +377,14 @@ object KeyguardBottomAreaViewBinder { view.isClickable = viewModel.isClickable if (viewModel.isClickable) { if (viewModel.useLongPress) { - val onTouchListener = KeyguardQuickAffordanceOnTouchListener( - view, - viewModel, - messageDisplayer, - vibratorHelper, - falsingManager, - ) + val onTouchListener = + KeyguardQuickAffordanceOnTouchListener( + view, + viewModel, + messageDisplayer, + vibratorHelper, + falsingManager, + ) view.setOnTouchListener(onTouchListener) view.setOnClickListener { messageDisplayer.invoke(R.string.keyguard_affordance_press_too_short) @@ -403,9 +403,7 @@ object KeyguardBottomAreaViewBinder { KeyguardBottomAreaVibrations.ShakeAnimationDuration.inWholeMilliseconds shakeAnimator.interpolator = CycleInterpolator(KeyguardBottomAreaVibrations.ShakeAnimationCycles) - shakeAnimator.doOnEnd { - view.translationX = 0f - } + shakeAnimator.doOnEnd { view.translationX = 0f } shakeAnimator.start() vibratorHelper?.vibrate(KeyguardBottomAreaVibrations.Shake) @@ -425,7 +423,7 @@ object KeyguardBottomAreaViewBinder { } @Deprecated("Deprecated as part of b/278057014") - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] private suspend fun updateButtonAlpha( view: View, viewModel: Flow<KeyguardQuickAffordanceViewModel>, @@ -456,7 +454,7 @@ object KeyguardBottomAreaViewBinder { } @Deprecated("Deprecated as part of b/278057014") - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] private class OnLongClickListener( private val falsingManager: FalsingManager?, private val viewModel: KeyguardQuickAffordanceViewModel, @@ -493,7 +491,7 @@ object KeyguardBottomAreaViewBinder { } @Deprecated("Deprecated as part of b/278057014") - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] private class OnClickListener( private val viewModel: KeyguardQuickAffordanceViewModel, private val falsingManager: FalsingManager, @@ -535,13 +533,7 @@ object KeyguardBottomAreaViewBinder { view: View, ) { activityStarter.postStartActivityDismissingKeyguard( - Intent(Intent.ACTION_SET_WALLPAPER).apply { - flags = Intent.FLAG_ACTIVITY_NEW_TASK - view.context - .getString(R.string.config_wallpaperPickerPackage) - .takeIf { it.isNotEmpty() } - ?.let { packageName -> setPackage(packageName) } - }, + WallpaperPickerIntentUtils.getIntent(view.context, LAUNCH_SOURCE_KEYGUARD), /* delay= */ 0, /* animationController= */ ActivityLaunchAnimator.Controller.fromView(view), /* customMessage= */ view.context.getString(R.string.keyguard_unlock_to_customize_ls) @@ -549,7 +541,7 @@ object KeyguardBottomAreaViewBinder { } @Deprecated("Deprecated as part of b/278057014") - //If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] + // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt] private data class ConfigurationBasedDimensions( val defaultBurnInPreventionYOffsetPx: Int, val buttonSizePx: Size, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index 4de9fc343af1..114fd94ebeb2 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -34,13 +34,13 @@ import com.android.internal.jank.InteractionJankMonitor import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD import com.android.keyguard.KeyguardClockSwitch.MISSING_CLOCK_ID import com.android.systemui.Flags.keyguardBottomAreaRefactor +import com.android.systemui.Flags.newAodTransition import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlagsClassic -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel @@ -384,7 +384,7 @@ object KeyguardRootViewBinder { } visibility = if (isVisible.value) View.VISIBLE else View.INVISIBLE } - featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> { + newAodTransition() -> { animateInIconTranslation(statusViewMigrated) if (isVisible.value) { CrossFadeHelper.fadeIn(this, animatorListener) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt index 6beef8ec1ff3..8514225fda90 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt @@ -17,19 +17,20 @@ package com.android.systemui.keyguard.ui.binder -import android.content.Intent import android.view.View import androidx.core.view.isVisible import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.systemui.res.R import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.view.LaunchableLinearLayout import com.android.systemui.common.ui.binder.IconViewBinder import com.android.systemui.common.ui.binder.TextViewBinder import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel +import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils +import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils.LAUNCH_SOURCE_KEYGUARD import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.res.R import com.android.systemui.statusbar.VibratorHelper import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.flow.distinctUntilChanged @@ -98,13 +99,7 @@ object KeyguardSettingsViewBinder { view: View, ) { activityStarter.postStartActivityDismissingKeyguard( - Intent(Intent.ACTION_SET_WALLPAPER).apply { - flags = Intent.FLAG_ACTIVITY_NEW_TASK - view.context - .getString(R.string.config_wallpaperPickerPackage) - .takeIf { it.isNotEmpty() } - ?.let { packageName -> setPackage(packageName) } - }, + WallpaperPickerIntentUtils.getIntent(view.context, LAUNCH_SOURCE_KEYGUARD), /* delay= */ 0, /* animationController= */ ActivityLaunchAnimator.Controller.fromView(view), /* customMessage= */ view.context.getString(R.string.keyguard_unlock_to_customize_ls) @@ -127,5 +122,4 @@ object KeyguardSettingsViewBinder { } .start() } - -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt index 0cf891c3f665..27b38c71d2e7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt @@ -33,7 +33,6 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusBarSec import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSection import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsModule.Companion.KEYGUARD_AMBIENT_INDICATION_AREA_SECTION import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection -import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines import java.util.Optional import javax.inject.Inject import javax.inject.Named @@ -62,14 +61,13 @@ constructor( aodBurnInSection: AodBurnInSection, communalTutorialIndicatorSection: CommunalTutorialIndicatorSection, clockSection: ClockSection, - smartspaceSection: SmartspaceSection + smartspaceSection: SmartspaceSection, ) : KeyguardBlueprint { override val id: String = DEFAULT override val sections = listOfNotNull( defaultIndicationAreaSection, - defaultDeviceEntryIconSection, defaultShortcutsSection, defaultAmbientIndicationAreaSection.getOrNull(), defaultSettingsPopupMenuSection, @@ -80,7 +78,8 @@ constructor( aodBurnInSection, communalTutorialIndicatorSection, clockSection, - smartspaceSection + smartspaceSection, + defaultDeviceEntryIconSection, // Add LAST: Intentionally has z-order above other views. ) companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt index 14e8f892e101..190ad44845d0 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt @@ -59,7 +59,6 @@ constructor( override val sections = listOfNotNull( defaultIndicationAreaSection, - defaultDeviceEntryIconSection, defaultAmbientIndicationAreaSection.getOrNull(), defaultSettingsPopupMenuSection, alignShortcutsToUdfpsSection, @@ -69,6 +68,7 @@ constructor( splitShadeGuidelines, aodNotificationIconsSection, aodBurnInSection, + defaultDeviceEntryIconSection, // Add LAST: Intentionally has z-order above other views. ) companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt index 0d397bff72ce..acbcf273214b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt @@ -65,7 +65,6 @@ constructor( override val sections = listOfNotNull( defaultIndicationAreaSection, - defaultDeviceEntryIconSection, defaultShortcutsSection, defaultAmbientIndicationAreaSection.getOrNull(), defaultSettingsPopupMenuSection, @@ -76,6 +75,7 @@ constructor( aodNotificationIconsSection, aodBurnInSection, communalTutorialIndicatorSection, + defaultDeviceEntryIconSection, // Add LAST: Intentionally has z-order above other views. ) companion object { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSection.kt index 790ddd533a8b..fac84981577f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSection.kt @@ -23,6 +23,7 @@ import android.graphics.Rect import android.util.DisplayMetrics import android.view.View import android.view.WindowManager +import android.widget.FrameLayout import androidx.annotation.VisibleForTesting import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet @@ -31,22 +32,28 @@ import com.android.keyguard.LockIconView import com.android.keyguard.LockIconViewController import com.android.systemui.Flags.keyguardBottomAreaRefactor import com.android.systemui.biometrics.AuthController +import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection +import com.android.systemui.keyguard.ui.binder.AlternateBouncerViewBinder import com.android.systemui.keyguard.ui.binder.DeviceEntryIconViewBinder import com.android.systemui.keyguard.ui.view.DeviceEntryIconView +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryBackgroundViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryForegroundViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryIconViewModel import com.android.systemui.plugins.FalsingManager import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.statusbar.NotificationShadeWindowController import dagger.Lazy import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi +/** Includes both the device entry icon and the alternate bouncer scrim. */ @ExperimentalCoroutinesApi class DefaultDeviceEntryIconSection @Inject @@ -62,14 +69,24 @@ constructor( private val deviceEntryForegroundViewModel: Lazy<DeviceEntryForegroundViewModel>, private val deviceEntryBackgroundViewModel: Lazy<DeviceEntryBackgroundViewModel>, private val falsingManager: Lazy<FalsingManager>, + private val alternateBouncerViewModel: Lazy<AlternateBouncerViewModel>, + private val notificationShadeWindowController: Lazy<NotificationShadeWindowController>, + @Application private val scope: CoroutineScope, ) : KeyguardSection() { private val deviceEntryIconViewId = R.id.device_entry_icon_view + private val alternateBouncerViewId = R.id.alternate_bouncer override fun addViews(constraintLayout: ConstraintLayout) { if (!keyguardBottomAreaRefactor() && !DeviceEntryUdfpsRefactor.isEnabled) { return } + if (DeviceEntryUdfpsRefactor.isEnabled) { + // The alternate bouncer scrim needs to be below the device entry icon view, so + // we add the view here before adding the device entry icon view. + View.inflate(context, R.layout.alternate_bouncer, constraintLayout) + } + notificationPanelView.findViewById<View>(R.id.lock_icon_view).let { notificationPanelView.removeView(it) } @@ -95,6 +112,14 @@ constructor( falsingManager.get(), ) } + constraintLayout.findViewById<FrameLayout?>(alternateBouncerViewId)?.let { + AlternateBouncerViewBinder.bind( + it, + alternateBouncerViewModel.get(), + scope, + notificationShadeWindowController.get(), + ) + } } else { constraintLayout.findViewById<LockIconView?>(R.id.lock_icon_view)?.let { lockIconViewController.get().setLockIconView(it) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt index 7512e518f03c..0588857f408d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt @@ -30,10 +30,13 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.res.R +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import javax.inject.Inject @@ -43,18 +46,24 @@ class DefaultNotificationStackScrollLayoutSection constructor( context: Context, private val featureFlags: FeatureFlags, + sceneContainerFlags: SceneContainerFlags, notificationPanelView: NotificationPanelView, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, + notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel, + ambientState: AmbientState, controller: NotificationStackScrollLayoutController, notificationStackSizeCalculator: NotificationStackSizeCalculator, private val smartspaceViewModel: KeyguardSmartspaceViewModel, ) : NotificationStackScrollLayoutSection( context, + sceneContainerFlags, notificationPanelView, sharedNotificationContainer, sharedNotificationContainerViewModel, + notificationStackAppearanceViewModel, + ambientState, controller, notificationStackSizeCalculator, ) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSectionsModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSectionsModule.kt index 37c00b61c4dd..a65149e6f3aa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSectionsModule.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSectionsModule.kt @@ -25,6 +25,7 @@ import javax.inject.Named @Module abstract class KeyguardSectionsModule { + @Module companion object { const val KEYGUARD_AMBIENT_INDICATION_AREA_SECTION = "keyguard_ambient_indication_area_section" diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt index 441f59d6df1d..a9e766e5f98d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/NotificationStackScrollLayoutSection.kt @@ -24,20 +24,28 @@ import androidx.constraintlayout.widget.ConstraintLayout import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator +import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationStackAppearanceViewBinder import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import kotlinx.coroutines.DisposableHandle abstract class NotificationStackScrollLayoutSection constructor( protected val context: Context, + private val sceneContainerFlags: SceneContainerFlags, private val notificationPanelView: NotificationPanelView, private val sharedNotificationContainer: SharedNotificationContainer, private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, + private val notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel, + private val ambientState: AmbientState, private val controller: NotificationStackScrollLayoutController, private val notificationStackSizeCalculator: NotificationStackSizeCalculator, ) : KeyguardSection() { @@ -68,9 +76,19 @@ constructor( SharedNotificationContainerBinder.bind( sharedNotificationContainer, sharedNotificationContainerViewModel, + sceneContainerFlags, controller, notificationStackSizeCalculator, ) + if (sceneContainerFlags.flexiNotifsEnabled()) { + NotificationStackAppearanceViewBinder.bind( + sharedNotificationContainer, + notificationStackAppearanceViewModel, + sceneContainerFlags, + ambientState, + controller, + ) + } } override fun removeViews(constraintLayout: ConstraintLayout) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt index f2559bad92b5..05ef5c386ab1 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeNotificationStackScrollLayoutSection.kt @@ -30,10 +30,13 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.KeyguardShadeMigrationNssl import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel import com.android.systemui.res.R +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import javax.inject.Inject @@ -43,18 +46,24 @@ class SplitShadeNotificationStackScrollLayoutSection constructor( context: Context, private val featureFlags: FeatureFlags, + sceneContainerFlags: SceneContainerFlags, notificationPanelView: NotificationPanelView, sharedNotificationContainer: SharedNotificationContainer, sharedNotificationContainerViewModel: SharedNotificationContainerViewModel, + notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel, + ambientState: AmbientState, controller: NotificationStackScrollLayoutController, notificationStackSizeCalculator: NotificationStackSizeCalculator, private val smartspaceViewModel: KeyguardSmartspaceViewModel, ) : NotificationStackScrollLayoutSection( context, + sceneContainerFlags, notificationPanelView, sharedNotificationContainer, sharedNotificationContainerViewModel, + notificationStackAppearanceViewModel, + ambientState, controller, notificationStackSizeCalculator, ) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt index 60f75f03609c..315626b6fcae 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt @@ -21,11 +21,11 @@ import android.content.Context import android.util.MathUtils import android.view.View.VISIBLE import com.android.app.animation.Interpolators +import com.android.systemui.Flags.newAodTransition import com.android.systemui.common.shared.model.SharedNotificationContainerPosition import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.flags.FeatureFlagsClassic -import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor @@ -49,6 +49,7 @@ import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -99,6 +100,10 @@ constructor( val goneToAodTransition = keyguardTransitionInteractor.goneToAodTransition + /** the shared notification container position *on the lockscreen* */ + val notificationPositionOnLockscreen: StateFlow<SharedNotificationContainerPosition> + get() = keyguardInteractor.sharedNotificationContainerPosition + /** An observable for the alpha level for the entire keyguard root view. */ val alpha: Flow<Float> = previewMode.flatMapLatest { @@ -249,8 +254,9 @@ constructor( if (previewMode.value.isInPreviewMode) { return } - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top, bottom) + ) } /** Is there an expanded pulse, are we animating in response? */ @@ -280,7 +286,7 @@ constructor( dozeParameters.displayNeedsBlanking -> false // We only want the appear animations to happen when the notifications // get fully hidden, since otherwise the un-hide animation overlaps. - featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> true + newAodTransition() -> true else -> fullyHidden } AnimatableEvent(fullyHidden, animate) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt index c03e4d950cae..539db7fb1ae3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt @@ -21,6 +21,7 @@ import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -37,6 +38,8 @@ constructor( deviceEntryInteractor: DeviceEntryInteractor, communalInteractor: CommunalInteractor, val longPress: KeyguardLongPressViewModel, + val keyguardRoot: KeyguardRootViewModel, + val notifications: NotificationsPlaceholderViewModel, ) { /** The key of the scene we should switch to when swiping up. */ val upDestinationSceneKey: StateFlow<SceneKey> = diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/util/WallpaperPickerIntentUtils.kt b/packages/SystemUI/src/com/android/systemui/keyguard/util/WallpaperPickerIntentUtils.kt new file mode 100644 index 000000000000..84e05661d05a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/util/WallpaperPickerIntentUtils.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.util + +import android.content.Context +import android.content.Intent +import com.android.systemui.res.R + +/** Provides function(s) to get intent for launching the Wallpaper Picker app. */ +object WallpaperPickerIntentUtils { + + fun getIntent(context: Context, launchSource: String): Intent { + return Intent(Intent.ACTION_SET_WALLPAPER).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK + context + .getString(R.string.config_wallpaperPickerPackage) + .takeIf { it.isNotEmpty() } + ?.let { packageName -> setPackage(packageName) } + putExtra(WALLPAPER_LAUNCH_SOURCE, launchSource) + } + } + + private const val WALLPAPER_LAUNCH_SOURCE = "com.android.wallpaper.LAUNCH_SOURCE" + const val LAUNCH_SOURCE_KEYGUARD = "app_launched_keyguard" +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt index 3941fd75ebaa..346d5c30a63e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt @@ -24,6 +24,7 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import javax.inject.Inject import kotlinx.coroutines.flow.map @@ -35,6 +36,7 @@ constructor( private val deviceEntryInteractor: DeviceEntryInteractor, val shadeHeaderViewModel: ShadeHeaderViewModel, val qsSceneAdapter: QSSceneAdapter, + val notifications: NotificationsPlaceholderViewModel, ) { /** Notifies that some content in quick settings was clicked. */ fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry() 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 8def457423e4..f3f9c916d705 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 @@ -97,6 +97,7 @@ constructor( /** Updates the visibility of the scene container. */ private fun hydrateVisibility() { applicationScope.launch { + // TODO(b/296114544): Combine with some global hun state to make it visible! sceneInteractor.transitionState .mapNotNull { state -> when (state) { diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt index 7fc409445f50..c88a04c24044 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt @@ -4,9 +4,11 @@ import android.content.Context import android.util.AttributeSet import android.view.View import android.view.WindowInsets +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel +import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import kotlinx.coroutines.flow.MutableStateFlow /** A root view of the main SysUI window that supports scenes. */ @@ -27,6 +29,8 @@ class SceneWindowRootView( fun init( viewModel: SceneContainerViewModel, containerConfig: SceneContainerConfig, + sharedNotificationContainer: SharedNotificationContainer, + flags: SceneContainerFlags, scenes: Set<Scene>, layoutInsetController: LayoutInsetsController, ) { @@ -37,6 +41,8 @@ class SceneWindowRootView( viewModel = viewModel, windowInsets = windowInsets, containerConfig = containerConfig, + sharedNotificationContainer = sharedNotificationContainer, + flags = flags, scenes = scenes, onVisibilityChangedInternal = { isVisible -> super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE) diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt index 17d6c9d319e8..4a839b8df9ba 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt @@ -31,10 +31,13 @@ import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.compose.ComposeFacade import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel +import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled +import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import java.time.Instant import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch @@ -47,6 +50,8 @@ object SceneWindowRootViewBinder { viewModel: SceneContainerViewModel, windowInsets: StateFlow<WindowInsets?>, containerConfig: SceneContainerConfig, + sharedNotificationContainer: SharedNotificationContainer, + flags: SceneContainerFlags, scenes: Set<Scene>, onVisibilityChangedInternal: (isVisible: Boolean) -> Unit, ) { @@ -91,6 +96,13 @@ object SceneWindowRootViewBinder { val legacyView = view.requireViewById<View>(R.id.legacy_window_root) view.addView(createVisibilityToggleView(legacyView)) + if (flags.flexiNotifsEnabled()) { + (sharedNotificationContainer.parent as? ViewGroup)?.removeView( + sharedNotificationContainer + ) + view.addView(sharedNotificationContainer) + } + launch { viewModel.isVisible.collect { isVisible -> onVisibilityChangedInternal(isVisible) diff --git a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java index f4d19dc2691d..d0585d3782c2 100644 --- a/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java +++ b/packages/SystemUI/src/com/android/systemui/scrim/ScrimView.java @@ -86,6 +86,8 @@ public class ScrimView extends View { public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + setFocusable(false); + setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); mDrawable = new ScrimDrawable(); mDrawable.setCallback(this); mColors = new ColorExtractor.GradientColors(); diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java index 335e65e71ae4..868fbceecafc 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java @@ -247,6 +247,14 @@ public class QuickSettingsController implements Dumpable { private Insets mCachedGestureInsets; /** + * The window width currently in effect -- used together with + * {@link QuickSettingsController#mCachedGestureInsets} to decide whether a back gesture should + * receive a horizontal swipe inwards from the left/right vertical edge of the screen. + * We cache this on ACTION_DOWN, and query it during both ACTION_DOWN and ACTION_MOVE events. + */ + private int mCachedWindowWidth; + + /** * The amount of progress we are currently in if we're transitioning to the full shade. * 0.0f means we're not transitioning yet, while 1 means we're all the way in the full * shade. This value can also go beyond 1.1 when we're overshooting! @@ -528,6 +536,7 @@ public class QuickSettingsController implements Dumpable { WindowMetrics windowMetrics = wm.getCurrentWindowMetrics(); mCachedGestureInsets = windowMetrics.getWindowInsets().getInsets( WindowInsets.Type.systemGestures()); + mCachedWindowWidth = windowMetrics.getBounds().width(); } /** @@ -536,7 +545,7 @@ public class QuickSettingsController implements Dumpable { */ public boolean shouldBackBypassQuickSettings(float touchX) { return (touchX < mCachedGestureInsets.left) - || (touchX > mKeyguardStatusBar.getWidth() - mCachedGestureInsets.right); + || (touchX > mCachedWindowWidth - mCachedGestureInsets.right); } /** Returns whether touch is within QS area */ @@ -2105,6 +2114,8 @@ public class QuickSettingsController implements Dumpable { ipw.println(mAnimatorExpand); ipw.print("mCachedGestureInsets="); ipw.println(mCachedGestureInsets); + ipw.print("mCachedWindowWidth="); + ipw.println(mCachedWindowWidth); ipw.print("mTransitioningToFullShadeProgress="); ipw.println(mTransitioningToFullShadeProgress); ipw.print("mDistanceForFullShadeTransition="); diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt index 374e8717f819..f40be4bbb678 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt @@ -69,6 +69,7 @@ abstract class ShadeViewProviderModule { sceneContainerFlags: SceneContainerFlags, viewModelProvider: Provider<SceneContainerViewModel>, containerConfigProvider: Provider<SceneContainerConfig>, + flagsProvider: Provider<SceneContainerFlags>, scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>, layoutInsetController: NotificationInsetsController, ): WindowRootView { @@ -78,6 +79,9 @@ abstract class ShadeViewProviderModule { sceneWindowRootView.init( viewModel = viewModelProvider.get(), containerConfig = containerConfigProvider.get(), + sharedNotificationContainer = + sceneWindowRootView.requireViewById(R.id.shared_notification_container), + flags = flagsProvider.get(), scenes = scenesProvider.get(), layoutInsetController = layoutInsetController, ) diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt index af880816914f..2a071def083a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt @@ -21,12 +21,13 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.shared.model.SceneKey +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel +import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn -import javax.inject.Inject /** Models UI state and handles user input for the shade scene. */ @SysUISingleton @@ -37,6 +38,7 @@ constructor( private val deviceEntryInteractor: DeviceEntryInteractor, val qsSceneAdapter: QSSceneAdapter, val shadeHeaderViewModel: ShadeHeaderViewModel, + val notifications: NotificationsPlaceholderViewModel, ) { /** The key of the scene we should switch to when swiping up. */ val upDestinationSceneKey: StateFlow<SceneKey> = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java index 68c48b9a261f..4a5089770b05 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java @@ -60,6 +60,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Button; import android.widget.EditText; import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; @@ -114,7 +115,6 @@ public final class KeyboardShortcutListSearch { private Button mButtonInput; private Button mButtonOpenApps; private Button mButtonSpecificApp; - private ImageView mEditTextCancel; private TextView mNoSearchResults; private final SparseArray<String> mSpecialCharacterNames = new SparseArray<>(); @@ -895,8 +895,9 @@ public final class KeyboardShortcutListSearch { // Do nothing. } }); - mEditTextCancel = keyboardShortcutsView.findViewById(R.id.keyboard_shortcuts_search_cancel); - mEditTextCancel.setOnClickListener(v -> mSearchEditText.setText(null)); + ImageButton editTextCancel = keyboardShortcutsView.findViewById( + R.id.keyboard_shortcuts_search_cancel); + editTextCancel.setOnClickListener(v -> mSearchEditText.setText(null)); } private void populateKeyboardShortcutSearchList(LinearLayout keyboardShortcutsLayout) { @@ -1276,12 +1277,12 @@ public final class KeyboardShortcutListSearch { private int getColorOfTextColorOnAccent() { return Utils.getColorAttrDefaultColor( - mContext, com.android.internal.R.attr.textColorOnAccent); + mContext, com.android.internal.R.attr.materialColorOnPrimary); } private int getColorOfTextColorSecondary() { return Utils.getColorAttrDefaultColor( - mContext, com.android.internal.R.attr.textColorSecondary); + mContext, com.android.internal.R.attr.materialColorOnSurface); } // Create the new data structure for handling the N-to-1 key mapping and other complex case. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index ae765e40c790..49c729eada1f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -160,8 +160,15 @@ constructor( var mUdfpsKeyguardViewControllerLegacy: UdfpsKeyguardViewControllerLegacy? = null /** The touch helper responsible for the drag down animation. */ - val touchHelper = DragDownHelper(falsingManager, falsingCollector, this, - naturalScrollingSettingObserver, context) + val touchHelper = + DragDownHelper( + falsingManager, + falsingCollector, + this, + naturalScrollingSettingObserver, + shadeRepository, + context + ) private val splitShadeOverScroller: SplitShadeLockScreenOverScroller by lazy { splitShadeOverScrollerFactory.create({ qS }, { nsslController }) @@ -756,6 +763,7 @@ class DragDownHelper( private val falsingCollector: FalsingCollector, private val dragDownCallback: LockscreenShadeTransitionController, private val naturalScrollingSettingObserver: NaturalScrollingSettingObserver, + private val shadeRepository: ShadeRepository, context: Context ) : Gefingerpoken { @@ -808,8 +816,9 @@ class DragDownHelper( startingChild = null initialTouchY = y initialTouchX = x - isTrackpadReverseScroll = !naturalScrollingSettingObserver.isNaturalScrollingEnabled - && isTrackpadScroll(true, event) + isTrackpadReverseScroll = + !naturalScrollingSettingObserver.isNaturalScrollingEnabled && + isTrackpadScroll(true, event) } MotionEvent.ACTION_MOVE -> { val h = (if (isTrackpadReverseScroll) -1 else 1) * (y - initialTouchY) @@ -875,6 +884,7 @@ class DragDownHelper( } isDraggingDown = false isTrackpadReverseScroll = false + shadeRepository.setLegacyLockscreenShadeTracking(false) } else { stopDragging() return false 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 860ad630be0c..0f14135f1d4c 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 @@ -64,6 +64,10 @@ import com.android.systemui.statusbar.notification.init.NotificationsControllerS import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProviderModule; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProviderImpl; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor; import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.logging.NotificationPanelLogger; import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl; @@ -268,4 +272,24 @@ public interface NotificationsModule { /** */ @Binds NotifLiveDataStore bindNotifLiveDataStore(NotifLiveDataStoreImpl notifLiveDataStoreImpl); + + /** */ + @Provides + @SysUISingleton + static VisualInterruptionDecisionProvider provideVisualInterruptionDecisionProvider( + Provider<NotificationInterruptStateProviderImpl> oldImplProvider, + Provider<VisualInterruptionDecisionProviderImpl> newImplProvider) { + if (VisualInterruptionRefactor.isEnabled()) { + return newImplProvider.get(); + } else { + return new NotificationInterruptStateProviderWrapper(oldImplProvider.get()); + } + } + + /** */ + @Binds + @IntoMap + @ClassKey(VisualInterruptionDecisionProvider.class) + CoreStartable startVisualInterruptionDecisionProvider( + VisualInterruptionDecisionProvider provider); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt index f732e8d74675..16bcd43dd877 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt @@ -31,6 +31,9 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti class NotificationInterruptStateProviderWrapper( private val wrapped: NotificationInterruptStateProvider ) : VisualInterruptionDecisionProvider { + init { + VisualInterruptionRefactor.assertInLegacyMode() + } @VisibleForTesting enum class DecisionImpl(override val shouldInterrupt: Boolean) : Decision { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt index de8863c64873..93fa85d61030 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.notification.interruption import com.android.internal.annotations.VisibleForTesting +import com.android.systemui.CoreStartable import com.android.systemui.statusbar.notification.collection.NotificationEntry /** @@ -26,7 +27,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry * pulsing while the device is dozing), displaying the notification as a bubble, and launching a * full-screen intent for the notification. */ -interface VisualInterruptionDecisionProvider { +interface VisualInterruptionDecisionProvider : CoreStartable { /** * Represents the decision to visually interrupt or not. * @@ -53,7 +54,7 @@ interface VisualInterruptionDecisionProvider { } /** Initializes the provider. */ - fun start() {} + override fun start() {} /** * Adds a [NotificationInterruptSuppressor] that can suppress visual interruptions. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt index 2b6e1a168b3c..39a87de89330 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt @@ -60,6 +60,10 @@ constructor( private val uiEventLogger: UiEventLogger, private val userTracker: UserTracker, ) : VisualInterruptionDecisionProvider { + init { + check(!VisualInterruptionRefactor.isUnexpectedlyInLegacyMode()) + } + interface Loggable { val uiEventId: UiEventEnum? val eventLogData: EventLogData? diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt index 2047c62cc5a9..ee797274deac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionSuppressor.kt @@ -73,6 +73,11 @@ abstract class VisualInterruptionCondition( override val uiEventId: UiEventEnum? = null, override val eventLogData: EventLogData? = null ) : VisualInterruptionSuppressor { + constructor( + types: Set<VisualInterruptionType>, + reason: String + ) : this(types, reason, /* uiEventId = */ null) + /** @return true if these interruptions should be suppressed right now. */ abstract fun shouldSuppress(): Boolean } @@ -84,6 +89,11 @@ abstract class VisualInterruptionFilter( override val uiEventId: UiEventEnum? = null, override val eventLogData: EventLogData? = null ) : VisualInterruptionSuppressor { + constructor( + types: Set<VisualInterruptionType>, + reason: String + ) : this(types, reason, /* uiEventId = */ null) + /** * @param entry the notification to consider suppressing * @return true if these interruptions should be suppressed for this notification right now diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java index b95e053ae508..8eda96f62257 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java @@ -156,7 +156,7 @@ public class NotificationBackgroundView extends View implements Dumpable { new int[]{com.android.internal.R.attr.state_hovered}, new int[]{}}, - new int[]{0, 0, tintColor} + new int[]{tintColor, tintColor, tintColor} ); mBackground.setTintMode(PorterDuff.Mode.SRC_ATOP); mBackground.setTintList(stateList); 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 46488c60fb0f..38d782b43c16 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 @@ -20,6 +20,7 @@ import static android.os.Trace.TRACE_TAG_APP; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL; +import static com.android.systemui.Flags.newAodTransition; import static com.android.systemui.flags.Flags.UNCLEARED_TRANSIENT_HUN_FIX; import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT; import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE; @@ -202,9 +203,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private final boolean mDebugRemoveAnimation; private final boolean mSensitiveRevealAnimEndabled; private final RefactorFlag mAnimatedInsets; - - private final boolean mNewAodTransition; - private int mContentHeight; private float mIntrinsicContentHeight; private int mPaddingBetweenElements; @@ -633,7 +631,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mIsSmallLandscapeLockscreenEnabled = mFeatureFlags.isEnabled( Flags.LOCKSCREEN_ENABLE_LANDSCAPE); mDebugLines = mFeatureFlags.isEnabled(Flags.NSSL_DEBUG_LINES); - mNewAodTransition = mFeatureFlags.isEnabled(Flags.NEW_AOD_TRANSITION); mDebugRemoveAnimation = mFeatureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION); mSensitiveRevealAnimEndabled = mFeatureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM); mAnimatedInsets = @@ -1462,7 +1459,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @VisibleForTesting public void updateStackHeight(float endHeight, float fraction) { - if (!mNewAodTransition) { + if (!newAodTransition()) { // During the (AOD<=>LS) transition where dozeAmount is changing, // apply dozeAmount to stack height instead of expansionFraction // to unfurl notifications on AOD=>LS wakeup (and furl up on LS=>AOD sleep) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt new file mode 100644 index 000000000000..7c10663bbb50 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.stack.data.repository + +import com.android.systemui.common.shared.model.SharedNotificationContainerPosition +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow + +/** A repository which holds state about and controlling the appearance of the NSSL */ +@SysUISingleton +class NotificationStackAppearanceRepository @Inject constructor() { + /** The position of the notification stack in the current scene */ + val stackPosition = MutableStateFlow(SharedNotificationContainerPosition(0f, 0f)) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt new file mode 100644 index 000000000000..820fe0b1f11e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.stack.domain.interactor + +import com.android.systemui.common.shared.model.SharedNotificationContainerPosition +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.notification.stack.data.repository.NotificationStackAppearanceRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** An interactor which controls the appearance of the NSSL */ +@SysUISingleton +class NotificationStackAppearanceInteractor +@Inject +constructor( + private val repository: NotificationStackAppearanceRepository, +) { + /** The position of the notification stack in the current scene */ + val stackPosition: StateFlow<SharedNotificationContainerPosition> + get() = repository.stackPosition.asStateFlow() + + /** Sets the position of the notification stack in the current scene */ + fun setStackPosition(position: SharedNotificationContainerPosition) { + check(position.top <= position.bottom) { "Invalid position: $position" } + repository.stackPosition.value = position + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt new file mode 100644 index 000000000000..5a71bd6fa116 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/SceneContainerFlagsExtension.kt @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.stack.shared + +import com.android.systemui.scene.shared.flag.SceneContainerFlags + +private const val FLEXI_NOTIFS = false + +/** + * Returns whether flexiglass is displaying notifications, which is currently an optional piece of + * flexiglass + */ +fun SceneContainerFlags.flexiNotifsEnabled() = FLEXI_NOTIFS && isEnabled() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt new file mode 100644 index 000000000000..4d6a6ee98b7d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackAppearanceViewBinder.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.stack.ui.viewbinder + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle +import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.scene.shared.flag.SceneContainerFlags +import com.android.systemui.statusbar.notification.stack.AmbientState +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController +import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel +import kotlinx.coroutines.launch + +/** Binds the shared notification container to its view-model. */ +object NotificationStackAppearanceViewBinder { + + @JvmStatic + fun bind( + view: SharedNotificationContainer, + viewModel: NotificationStackAppearanceViewModel, + sceneContainerFlags: SceneContainerFlags, + ambientState: AmbientState, + controller: NotificationStackScrollLayoutController, + ) { + view.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.CREATED) { + launch { + viewModel.stackPosition.collect { + controller.updateTopPadding( + it.top, + controller.isAddOrRemoveAnimationPending + ) + } + } + launch { + viewModel.expandFraction.collect { + ambientState.expansionFraction = it + controller.expandedHeight = it * controller.view.height + } + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt index 0ff1bec84d16..44006fc3fd4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt @@ -19,8 +19,10 @@ package com.android.systemui.statusbar.notification.stack.ui.viewbinder import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator +import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel import kotlinx.coroutines.DisposableHandle @@ -33,6 +35,7 @@ object SharedNotificationContainerBinder { fun bind( view: SharedNotificationContainer, viewModel: SharedNotificationContainerViewModel, + sceneContainerFlags: SceneContainerFlags, controller: NotificationStackScrollLayoutController, notificationStackSizeCalculator: NotificationStackSizeCalculator, ): DisposableHandle { @@ -68,10 +71,12 @@ object SharedNotificationContainerBinder { .collect { controller.setMaxDisplayedNotifications(it) } } - launch { - viewModel.position.collect { - val animate = it.animate || controller.isAddOrRemoveAnimationPending() - controller.updateTopPadding(it.top, animate) + if (!sceneContainerFlags.flexiNotifsEnabled()) { + launch { + viewModel.position.collect { + val animate = it.animate || controller.isAddOrRemoveAnimationPending + controller.updateTopPadding(it.top, animate) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt new file mode 100644 index 000000000000..b86993486097 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.statusbar.notification.stack.ui.viewmodel + +import com.android.systemui.common.shared.model.SharedNotificationContainerPosition +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow + +/** ViewModel which represents the state of the NSSL/Controller in the world of flexiglass */ +@SysUISingleton +class NotificationStackAppearanceViewModel +@Inject +constructor( + stackAppearanceInteractor: NotificationStackAppearanceInteractor, + shadeInteractor: ShadeInteractor, +) { + /** The expansion fraction from the top of the notification shade */ + val expandFraction: Flow<Float> = shadeInteractor.shadeExpansion + + /** The position of the notification stack in the current scene */ + val stackPosition: Flow<SharedNotificationContainerPosition> = + stackAppearanceInteractor.stackPosition +} 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 new file mode 100644 index 000000000000..7def6feedb41 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.stack.ui.viewmodel + +import com.android.systemui.common.shared.model.SharedNotificationContainerPosition +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.scene.shared.flag.SceneContainerFlags +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor +import com.android.systemui.statusbar.notification.stack.shared.flexiNotifsEnabled +import javax.inject.Inject + +/** + * ViewModel used by the Notification placeholders inside the scene container to update the + * [NotificationStackAppearanceInteractor], and by extension control the NSSL. + */ +@SysUISingleton +class NotificationsPlaceholderViewModel +@Inject +constructor( + private val interactor: NotificationStackAppearanceInteractor, + flags: SceneContainerFlags, + featureFlags: FeatureFlagsClassic, +) { + /** DEBUG: whether the placeholder "Notifications" text should be shown. */ + val isPlaceholderTextVisible: Boolean = !flags.flexiNotifsEnabled() + + /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */ + val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES) + + /** DEBUG: whether the debug logging should be output. */ + val isDebugLoggingEnabled: Boolean = flags.flexiNotifsEnabled() + + /** Sets the position of the notification stack in the current scene */ + fun setPlaceholderPositionInWindow(top: Float, bottom: Float) { + interactor.setStackPosition(SharedNotificationContainerPosition(top, bottom)) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt index d6b6f75b3186..09b4dfa31788 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import com.android.systemui.common.shared.model.SharedNotificationContainerPosition +import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState @@ -25,7 +26,10 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import com.android.systemui.util.kotlin.sample import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combineTransform import kotlinx.coroutines.flow.distinctUntilChanged @@ -33,12 +37,14 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.stateIn /** View-model for the shared notification container, used by both the shade and keyguard spaces */ class SharedNotificationContainerViewModel @Inject constructor( private val interactor: SharedNotificationContainerInteractor, + @Application applicationScope: CoroutineScope, keyguardInteractor: KeyguardInteractor, keyguardTransitionInteractor: KeyguardTransitionInteractor, private val shadeInteractor: ShadeInteractor, @@ -103,32 +109,38 @@ constructor( * * When the shade is expanding, the position is controlled by... the shade. */ - val position: Flow<SharedNotificationContainerPosition> = - isOnLockscreenWithoutShade.flatMapLatest { onLockscreen -> - if (onLockscreen) { - combine( - keyguardInteractor.sharedNotificationContainerPosition, - configurationBasedDimensions - ) { position, config -> - if (config.useSplitShade) { - position.copy(top = 0f) - } else { - position + val position: StateFlow<SharedNotificationContainerPosition> = + isOnLockscreenWithoutShade + .flatMapLatest { onLockscreen -> + if (onLockscreen) { + combine( + keyguardInteractor.sharedNotificationContainerPosition, + configurationBasedDimensions + ) { position, config -> + if (config.useSplitShade) { + position.copy(top = 0f) + } else { + position + } + } + } else { + interactor.topPosition.sample(shadeInteractor.qsExpansion, ::Pair).map { + (top, qsExpansion) -> + // When QS expansion > 0, it should directly set the top padding so do not + // animate it + val animate = qsExpansion == 0f + keyguardInteractor.sharedNotificationContainerPosition.value.copy( + top = top, + animate = animate + ) } - } - } else { - interactor.topPosition.sample(shadeInteractor.qsExpansion, ::Pair).map { - (top, qsExpansion) -> - // When QS expansion > 0, it should directly set the top padding so do not - // animate it - val animate = qsExpansion == 0f - keyguardInteractor.sharedNotificationContainerPosition.value.copy( - top = top, - animate = animate - ) } } - } + .stateIn( + scope = applicationScope, + started = SharingStarted.WhileSubscribed(), + initialValue = SharedNotificationContainerPosition(0f, 0f), + ) /** * Under certain scenarios, such as swiping up on the lockscreen, the container will need to be @@ -156,15 +168,11 @@ constructor( // When to limit notifications: on lockscreen with an unexpanded shade. Also, recalculate // when the notification stack has changed internally val limitedNotifications = - combineTransform( - isOnLockscreen, + combine( position, - shadeInteractor.shadeExpansion, interactor.notificationStackChanged.onStart { emit(Unit) }, - ) { isOnLockscreen, position, shadeExpansion, _ -> - if (isOnLockscreen && shadeExpansion == 0f) { - emit(calculateSpace(position.bottom - position.top)) - } + ) { position, _ -> + calculateSpace(position.bottom - position.top) } // When to show unlimited notifications: When the shade is fully expanded and the user is @@ -178,11 +186,14 @@ constructor( emit(-1) } } - - return merge( - limitedNotifications, - unlimitedNotifications, - ) + return isOnLockscreenWithoutShade + .flatMapLatest { isOnLockscreenWithoutShade -> + if (isOnLockscreenWithoutShade) { + limitedNotifications + } else { + unlimitedNotifications + } + } .distinctUntilChanged() } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 46675c2889d8..645769cdd586 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -27,6 +27,7 @@ import static androidx.core.view.ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_ import static androidx.lifecycle.Lifecycle.State.RESUMED; import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME; +import static com.android.systemui.Flags.lightRevealMigration; import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL; import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF; import static com.android.systemui.statusbar.StatusBarState.SHADE; @@ -205,7 +206,7 @@ import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.init.NotificationsController; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor; @@ -239,6 +240,8 @@ import com.android.wm.shell.startingsurface.StartingSurface; import dalvik.annotation.optimization.NeverCompile; +import dagger.Lazy; + import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; @@ -250,8 +253,6 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import dagger.Lazy; - /** * A class handling initialization and coordination between some of the key central surfaces in * System UI: The notification shade, the keyguard (lockscreen), and the status bar. @@ -457,7 +458,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final NotificationGutsManager mGutsManager; private final ShadeExpansionStateManager mShadeExpansionStateManager; private final KeyguardViewMediator mKeyguardViewMediator; - protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider; + private final VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider; private final BrightnessSliderController.Factory mBrightnessSliderFactory; private final FeatureFlags mFeatureFlags; private final FragmentService mFragmentService; @@ -618,7 +619,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { FalsingCollector falsingCollector, BroadcastDispatcher broadcastDispatcher, NotificationGutsManager notificationGutsManager, - NotificationInterruptStateProvider notificationInterruptStateProvider, + VisualInterruptionDecisionProvider visualInterruptionDecisionProvider, ShadeExpansionStateManager shadeExpansionStateManager, KeyguardViewMediator keyguardViewMediator, DisplayMetrics displayMetrics, @@ -725,7 +726,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mFalsingManager = falsingManager; mBroadcastDispatcher = broadcastDispatcher; mGutsManager = notificationGutsManager; - mNotificationInterruptStateProvider = notificationInterruptStateProvider; + mVisualInterruptionDecisionProvider = visualInterruptionDecisionProvider; mShadeExpansionStateManager = shadeExpansionStateManager; mKeyguardViewMediator = keyguardViewMediator; mDisplayMetrics = displayMetrics; @@ -953,7 +954,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { @Override public void onKeyguardGoingAwayChanged() { - if (mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (lightRevealMigration()) { // This code path is not used if the KeyguardTransitionRepository is managing // the lightreveal scrim. return; @@ -1222,7 +1223,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { }); mScrimController.attachViews(scrimBehind, notificationsScrim, scrimInFront); - if (mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (lightRevealMigration()) { LightRevealScrimViewBinder.bind( mLightRevealScrim, mLightRevealScrimViewModelLazy.get()); } @@ -2355,7 +2356,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { return; } - if (mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (lightRevealMigration()) { return; } @@ -3001,7 +3002,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { return; } - if (!mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION)) { + if (!lightRevealMigration()) { mLightRevealScrim.setAlpha(mScrimController.getState().getMaxLightRevealScrimAlpha()); } } @@ -3156,7 +3157,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { @Override public void onDozeAmountChanged(float linear, float eased) { - if (!mFeatureFlags.isEnabled(Flags.LIGHT_REVEAL_MIGRATION) + if (!lightRevealMigration() && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) { mLightRevealScrim.setRevealAmount(1f - linear); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java index 1f9952a8d4ec..a62a1ed9f0c0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java @@ -15,7 +15,7 @@ */ package com.android.systemui.statusbar.phone; -import static com.android.systemui.flags.Flags.NEW_AOD_TRANSITION; +import static com.android.systemui.Flags.newAodTransition; import android.content.Context; import android.content.res.Resources; @@ -106,9 +106,6 @@ public class LegacyNotificationIconAreaControllerImpl implements private NotificationIconContainer mAodIcons; private final ArrayList<Rect> mTintAreas = new ArrayList<>(); private final Context mContext; - - private final boolean mNewAodTransition; - private int mAodIconAppearTranslation; private boolean mAnimationsEnabled; @@ -145,7 +142,6 @@ public class LegacyNotificationIconAreaControllerImpl implements mContrastColorUtil = ContrastColorUtil.getInstance(context); mContext = context; mStatusBarStateController = statusBarStateController; - mNewAodTransition = featureFlags.isEnabled(NEW_AOD_TRANSITION); mStatusBarStateController.addCallback(this); mMediaManager = notificationMediaManager; mDozeParameters = dozeParameters; @@ -600,7 +596,7 @@ public class LegacyNotificationIconAreaControllerImpl implements boolean animate = true; if (!mBypassController.getBypassEnabled()) { animate = mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking(); - if (!mNewAodTransition) { + if (!newAodTransition()) { // We only want the appear animations to happen when the notifications get fully // hidden, since otherwise the unhide animation overlaps animate &= fullyHidden; @@ -640,7 +636,7 @@ public class LegacyNotificationIconAreaControllerImpl implements mAodIconsVisible = visible; mAodIcons.animate().cancel(); if (animate) { - if (mNewAodTransition) { + if (newAodTransition()) { // Let's make sure the icon are translated to 0, since we cancelled it above animateInAodIconTranslation(); if (mAodIconsVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 3e753a589a84..ae04eaf49b65 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -396,9 +396,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump states[i].setDefaultScrimAlpha(mDefaultScrimAlpha); } - mScrimBehind.setDefaultFocusHighlightEnabled(false); - mNotificationsScrim.setDefaultFocusHighlightEnabled(false); - mScrimInFront.setDefaultFocusHighlightEnabled(false); mTransparentScrimBackground = notificationsScrim.getResources() .getBoolean(R.bool.notification_scrim_transparent); updateScrims(); @@ -509,12 +506,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump applyState(); - // Scrim might acquire focus when user is navigating with a D-pad or a keyboard. - // We need to disable focus otherwise AOD would end up with a gray overlay. - mScrimInFront.setFocusable(!state.isLowPowerState()); - mScrimBehind.setFocusable(!state.isLowPowerState()); - mNotificationsScrim.setFocusable(!state.isLowPowerState()); - mScrimInFront.setBlendWithMainColor(state.shouldBlendWithMainColor()); // Cancel blanking transitions that were pending before we requested a new state diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index dbee080f238d..2e1a0770757b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -72,7 +72,6 @@ import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorCon import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.provider.LaunchFullScreenIntentProvider; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; @@ -115,7 +114,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final NotificationLockscreenUserManager mLockscreenUserManager; private final com.android.systemui.shade.ShadeController mShadeController; private final KeyguardStateController mKeyguardStateController; - private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final LockPatternUtils mLockPatternUtils; private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback; private final ActivityIntentHelper mActivityIntentHelper; @@ -154,7 +152,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit NotificationLockscreenUserManager lockscreenUserManager, ShadeController shadeController, KeyguardStateController keyguardStateController, - NotificationInterruptStateProvider notificationInterruptStateProvider, LockPatternUtils lockPatternUtils, StatusBarRemoteInputCallback remoteInputCallback, ActivityIntentHelper activityIntentHelper, @@ -187,7 +184,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit mLockscreenUserManager = lockscreenUserManager; mShadeController = shadeController; mKeyguardStateController = keyguardStateController; - mNotificationInterruptStateProvider = notificationInterruptStateProvider; mLockPatternUtils = lockPatternUtils; mStatusBarRemoteInputCallback = remoteInputCallback; mActivityIntentHelper = activityIntentHelper; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index 07e2571bcb38..8e9c0384987d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -14,6 +14,9 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE; import static com.android.systemui.statusbar.phone.CentralSurfaces.CLOSE_PANEL_WHEN_EMPTIED; import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG; @@ -29,6 +32,8 @@ import android.util.Log; import android.util.Slog; import android.view.View; +import androidx.annotation.NonNull; + import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.InitController; import com.android.systemui.dagger.SysUISingleton; @@ -54,7 +59,10 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition; import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionFilter; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; @@ -63,6 +71,8 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import java.util.Set; + import javax.inject.Inject; @SysUISingleton @@ -163,7 +173,14 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu initController.addPostInitTask(() -> { mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied); mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse); - visualInterruptionDecisionProvider.addLegacySuppressor(mInterruptSuppressor); + if (VisualInterruptionRefactor.isEnabled()) { + visualInterruptionDecisionProvider.addCondition(mAlertsDisabledCondition); + visualInterruptionDecisionProvider.addCondition(mVrModeCondition); + visualInterruptionDecisionProvider.addFilter(mNeedsRedactionFilter); + visualInterruptionDecisionProvider.addCondition(mPanelsDisabledCondition); + } else { + visualInterruptionDecisionProvider.addLegacySuppressor(mInterruptSuppressor); + } mLockscreenUserManager.setUpWithPresenter(this); mGutsManager.setUpWithPresenter( this, mNotifListContainer, mOnSettingsClickListener); @@ -306,4 +323,54 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu return !mNotificationAlertsInteractor.areNotificationAlertsEnabled(); } }; + + private final VisualInterruptionCondition mAlertsDisabledCondition = + new VisualInterruptionCondition(Set.of(PEEK, PULSE, BUBBLE), + "notification alerts disabled") { + @Override + public boolean shouldSuppress() { + return !mNotificationAlertsInteractor.areNotificationAlertsEnabled(); + } + }; + + private final VisualInterruptionCondition mVrModeCondition = + new VisualInterruptionCondition(Set.of(PEEK, BUBBLE), "device is in VR mode") { + @Override + public boolean shouldSuppress() { + return isDeviceInVrMode(); + } + }; + + private final VisualInterruptionFilter mNeedsRedactionFilter = + new VisualInterruptionFilter(Set.of(PEEK), "needs redaction on public lockscreen") { + @Override + public boolean shouldSuppress(@NonNull NotificationEntry entry) { + if (!mKeyguardStateController.isOccluded()) { + return false; + } + + if (!mLockscreenUserManager.needsRedaction(entry)) { + return false; + } + + final int currentUserId = mLockscreenUserManager.getCurrentUserId(); + final boolean currentUserPublic = mLockscreenUserManager.isLockscreenPublicMode( + currentUserId); + + final int notificationUserId = entry.getSbn().getUserId(); + final boolean notificationUserPublic = + mLockscreenUserManager.isLockscreenPublicMode(notificationUserId); + + // TODO(b/135046837): we can probably relax this with dynamic privacy + return currentUserPublic || notificationUserPublic; + } + }; + + private final VisualInterruptionCondition mPanelsDisabledCondition = + new VisualInterruptionCondition(Set.of(PEEK), "disabled panel") { + @Override + public boolean shouldSuppress() { + return !mCommandQueue.panelsEnabled(); + } + }; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt index 3522b9a13989..4f702d7534cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt @@ -109,8 +109,9 @@ constructor( { int1 = subId str1 = displayInfo.toString() + bool1 = displayInfo.isRoaming }, - { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1" }, + { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1 isRoaming=$bool1" }, ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt index 125fd9be15c7..4fb99c24c8ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt @@ -46,6 +46,8 @@ import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected @@ -105,6 +107,7 @@ class MobileConnectionRepositoryImpl( private val bgDispatcher: CoroutineDispatcher, logger: MobileInputLogger, override val tableLogBuffer: TableLogBuffer, + flags: FeatureFlagsClassic, scope: CoroutineScope, ) : MobileConnectionRepository { init { @@ -201,9 +204,15 @@ class MobileConnectionRepositoryImpl( .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val isRoaming = - callbackEvents - .mapNotNull { it.onServiceStateChanged } - .map { it.serviceState.roaming } + if (flags.isEnabled(ROAMING_INDICATOR_VIA_DISPLAY_INFO)) { + callbackEvents + .mapNotNull { it.onDisplayInfoChanged } + .map { it.telephonyDisplayInfo.isRoaming } + } else { + callbackEvents + .mapNotNull { it.onServiceStateChanged } + .map { it.serviceState.roaming } + } .stateIn(scope, SharingStarted.WhileSubscribed(), false) override val operatorAlphaShort = @@ -432,6 +441,7 @@ class MobileConnectionRepositoryImpl( private val logger: MobileInputLogger, private val carrierConfigRepository: CarrierConfigRepository, private val mobileMappingsProxy: MobileMappingsProxy, + private val flags: FeatureFlagsClassic, @Background private val bgDispatcher: CoroutineDispatcher, @Application private val scope: CoroutineScope, ) { @@ -456,6 +466,7 @@ class MobileConnectionRepositoryImpl( bgDispatcher, logger, mobileLogger, + flags, scope, ) } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java index 6a08eeac8108..7feab9141da2 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java @@ -195,6 +195,7 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase { mKeyguardUnlockAnimationController, mSecureSettings, mExecutor, + mExecutor, mDumpManager, mClockEventController, mLogBuffer, diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index d84c2c0415eb..cb26e6193ae6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -157,6 +157,7 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); mController.init(); + mExecutor.runAllReady(); verify(mSecureSettings).registerContentObserverForUser( eq(Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK), anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL)); @@ -212,6 +213,7 @@ public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchContro ArgumentCaptor<ContentObserver> observerCaptor = ArgumentCaptor.forClass(ContentObserver.class); mController.init(); + mExecutor.runAllReady(); verify(mSecureSettings).registerContentObserverForUser( eq(Settings.Secure.LOCK_SCREEN_WEATHER_ENABLED), anyBoolean(), observerCaptor.capture(), eq(UserHandle.USER_ALL)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt index b4b02a2dfb93..a1b801cd3d3f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt @@ -55,6 +55,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository @@ -151,9 +152,11 @@ class SideFpsControllerTest : SysuiTestCase() { mock(StatusBarStateController::class.java), mock(KeyguardStateController::class.java), keyguardBouncerRepository, + FakeFingerprintPropertyRepository(), FakeBiometricSettingsRepository(), FakeSystemClock(), mock(KeyguardUpdateMonitor::class.java), + testScope.backgroundScope, ) displayStateInteractor = DisplayStateInteractorImpl( diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt index a49150f50d07..9bff88bbf2dd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt @@ -21,6 +21,7 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -111,9 +112,11 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : mock(StatusBarStateController::class.java), mock(KeyguardStateController::class.java), keyguardBouncerRepository, + FakeFingerprintPropertyRepository(), mock(BiometricSettingsRepository::class.java), mock(SystemClock::class.java), mKeyguardUpdateMonitor, + testScope.backgroundScope, ) mKeyguardTransitionInteractor = KeyguardTransitionInteractorFactory.create( diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt index 2d8adca04a5e..0d44ed30431f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt @@ -19,11 +19,13 @@ package com.android.systemui.bouncer.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.Flags import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl +import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository -import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.policy.KeyguardStateController @@ -31,7 +33,7 @@ import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.time.SystemClock import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestCoroutineScope +import kotlinx.coroutines.test.TestScope import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Before @@ -47,8 +49,7 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { private lateinit var underTest: AlternateBouncerInteractor private lateinit var bouncerRepository: KeyguardBouncerRepository private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository - private lateinit var deviceEntryFingerprintAuthRepository: - FakeDeviceEntryFingerprintAuthRepository + private lateinit var fingerprintPropertyRepository: FakeFingerprintPropertyRepository @Mock private lateinit var statusBarStateController: StatusBarStateController @Mock private lateinit var keyguardStateController: KeyguardStateController @Mock private lateinit var systemClock: SystemClock @@ -61,19 +62,21 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { bouncerRepository = KeyguardBouncerRepositoryImpl( FakeSystemClock(), - TestCoroutineScope(), + TestScope().backgroundScope, bouncerLogger, ) biometricSettingsRepository = FakeBiometricSettingsRepository() - deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository() + fingerprintPropertyRepository = FakeFingerprintPropertyRepository() underTest = AlternateBouncerInteractor( statusBarStateController, keyguardStateController, bouncerRepository, + fingerprintPropertyRepository, biometricSettingsRepository, systemClock, keyguardUpdateMonitor, + TestScope().backgroundScope, ) } @@ -156,7 +159,17 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { } @Test + fun canShowAlternateBouncerForFingerprint_rearFps() { + mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) + givenCanShowAlternateBouncer() + fingerprintPropertyRepository.supportsRearFps() // does not support alternate bouncer + + assertFalse(underTest.canShowAlternateBouncerForFingerprint()) + } + + @Test fun alternateBouncerUiAvailable_fromMultipleSources() { + mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) assertFalse(bouncerRepository.alternateBouncerUIAvailable.value) // GIVEN there are two different sources indicating the alternate bouncer is available @@ -178,7 +191,12 @@ class AlternateBouncerInteractorTest : SysuiTestCase() { } private fun givenCanShowAlternateBouncer() { - bouncerRepository.setAlternateBouncerUIAvailable(true) + if (DeviceEntryUdfpsRefactor.isEnabled) { + fingerprintPropertyRepository.supportsUdfps() + } else { + bouncerRepository.setAlternateBouncerUIAvailable(true) + } + biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true) whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false) diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt index 50d2fd22d0fa..1e8073246f98 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt @@ -25,6 +25,7 @@ import com.android.systemui.authentication.shared.model.AuthenticationMethodMode import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor import com.android.systemui.res.R import com.android.systemui.scene.SceneTestUtils import com.google.common.truth.Truth.assertThat @@ -37,28 +38,38 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class BouncerInteractorTest : SysuiTestCase() { + @Mock private lateinit var keyguardFaceAuthInteractor: KeyguardFaceAuthInteractor + private val utils = SceneTestUtils(this) private val testScope = utils.testScope private val authenticationInteractor = utils.authenticationInteractor() - private val underTest = - utils.bouncerInteractor( - authenticationInteractor = authenticationInteractor, - ) + + private lateinit var underTest: BouncerInteractor @Before fun setUp() { + MockitoAnnotations.initMocks(this) overrideResource(R.string.keyguard_enter_your_pin, MESSAGE_ENTER_YOUR_PIN) overrideResource(R.string.keyguard_enter_your_password, MESSAGE_ENTER_YOUR_PASSWORD) overrideResource(R.string.keyguard_enter_your_pattern, MESSAGE_ENTER_YOUR_PATTERN) overrideResource(R.string.kg_wrong_pin, MESSAGE_WRONG_PIN) overrideResource(R.string.kg_wrong_password, MESSAGE_WRONG_PASSWORD) overrideResource(R.string.kg_wrong_pattern, MESSAGE_WRONG_PATTERN) + + underTest = + utils.bouncerInteractor( + authenticationInteractor = authenticationInteractor, + keyguardFaceAuthInteractor = keyguardFaceAuthInteractor, + ) } @Test @@ -325,6 +336,13 @@ class BouncerInteractorTest : SysuiTestCase() { assertThat(utils.powerRepository.userTouchRegistered).isTrue() } + @Test + fun intentionalUserInputEvent_notifiesFaceAuthInteractor() = + testScope.runTest { + underTest.onIntentionalUserInput() + verify(keyguardFaceAuthInteractor).onPrimaryBouncerUserInput() + } + private fun assertTryAgainMessage( message: String?, time: Int, diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index e0567a4c6de5..16cfa2398fd5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.communal.domain.interactor import android.app.smartspace.SmartspaceTarget -import android.provider.Settings import android.provider.Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED import android.widget.RemoteViews import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -99,24 +98,6 @@ class CommunalInteractorTest : SysuiTestCase() { } @Test - fun tutorial_tutorialNotCompletedAndKeyguardVisible_showTutorialContent() = - testScope.runTest { - // Keyguard showing, and tutorial not started. - keyguardRepository.setKeyguardShowing(true) - keyguardRepository.setKeyguardOccluded(false) - tutorialRepository.setTutorialSettingState( - Settings.Secure.HUB_MODE_TUTORIAL_NOT_STARTED - ) - - val communalContent by collectLastValue(underTest.communalContent) - - assertThat(communalContent!!).isNotEmpty() - communalContent!!.forEach { model -> - assertThat(model is CommunalContentModel.Tutorial).isTrue() - } - } - - @Test fun widget_tutorialCompletedAndWidgetsAvailable_showWidgetContent() = testScope.runTest { // Keyguard showing, and tutorial completed. @@ -145,12 +126,11 @@ class CommunalInteractorTest : SysuiTestCase() { ) widgetRepository.setCommunalWidgets(widgets) - val communalContent by collectLastValue(underTest.communalContent) + val widgetContent by collectLastValue(underTest.widgetContent) - assertThat(communalContent!!).isNotEmpty() - communalContent!!.forEachIndexed { index, model -> - assertThat((model as CommunalContentModel.Widget).appWidgetId) - .isEqualTo(widgets[index].appWidgetId) + assertThat(widgetContent!!).isNotEmpty() + widgetContent!!.forEachIndexed { index, model -> + assertThat(model.appWidgetId).isEqualTo(widgets[index].appWidgetId) } } @@ -183,48 +163,9 @@ class CommunalInteractorTest : SysuiTestCase() { val targets = listOf(target1, target2, target3) smartspaceRepository.setLockscreenSmartspaceTargets(targets) - val communalContent by collectLastValue(underTest.communalContent) - assertThat(communalContent?.size).isEqualTo(1) - assertThat(communalContent?.get(0)?.key).isEqualTo("smartspace_target3") - } - - @Test - fun smartspace_smartspaceAndWidgetsAvailable_showSmartspaceAndWidgetContent() = - testScope.runTest { - // Keyguard showing, and tutorial completed. - keyguardRepository.setKeyguardShowing(true) - keyguardRepository.setKeyguardOccluded(false) - tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) - - // Widgets available. - val widgets = - listOf( - CommunalWidgetContentModel( - appWidgetId = 0, - priority = 30, - providerInfo = mock(), - ), - CommunalWidgetContentModel( - appWidgetId = 1, - priority = 20, - providerInfo = mock(), - ), - ) - widgetRepository.setCommunalWidgets(widgets) - - // Smartspace available. - val target = mock(SmartspaceTarget::class.java) - whenever(target.smartspaceTargetId).thenReturn("target") - whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER) - whenever(target.remoteViews).thenReturn(mock(RemoteViews::class.java)) - smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target)) - - val communalContent by collectLastValue(underTest.communalContent) - - assertThat(communalContent?.size).isEqualTo(3) - assertThat(communalContent?.get(0)?.key).isEqualTo("smartspace_target") - assertThat(communalContent?.get(1)?.key).isEqualTo("widget_0") - assertThat(communalContent?.get(2)?.key).isEqualTo("widget_1") + val smartspaceContent by collectLastValue(underTest.smartspaceContent) + assertThat(smartspaceContent?.size).isEqualTo(1) + assertThat(smartspaceContent?.get(0)?.key).isEqualTo("smartspace_target3") } @Test @@ -236,55 +177,11 @@ class CommunalInteractorTest : SysuiTestCase() { // Media is playing. mediaRepository.mediaPlaying.value = true - val communalContent by collectLastValue(underTest.communalContent) - - assertThat(communalContent?.size).isEqualTo(1) - assertThat(communalContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java) - assertThat(communalContent?.get(0)?.key).isEqualTo(CommunalContentModel.UMO_KEY) - } - - @Test - fun ordering_smartspaceBeforeUmoBeforeWidgets() = - testScope.runTest { - tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED) - - // Widgets available. - val widgets = - listOf( - CommunalWidgetContentModel( - appWidgetId = 0, - priority = 30, - providerInfo = mock(), - ), - CommunalWidgetContentModel( - appWidgetId = 1, - priority = 20, - providerInfo = mock(), - ), - ) - widgetRepository.setCommunalWidgets(widgets) - - // Smartspace available. - val target = mock(SmartspaceTarget::class.java) - whenever(target.smartspaceTargetId).thenReturn("target") - whenever(target.featureType).thenReturn(SmartspaceTarget.FEATURE_TIMER) - whenever(target.remoteViews).thenReturn(mock(RemoteViews::class.java)) - smartspaceRepository.setLockscreenSmartspaceTargets(listOf(target)) - - // Media playing. - mediaRepository.mediaPlaying.value = true + val umoContent by collectLastValue(underTest.umoContent) - val communalContent by collectLastValue(underTest.communalContent) - - // Order is smart space, then UMO, then widget content. - assertThat(communalContent?.size).isEqualTo(4) - assertThat(communalContent?.get(0)) - .isInstanceOf(CommunalContentModel.Smartspace::class.java) - assertThat(communalContent?.get(1)).isInstanceOf(CommunalContentModel.Umo::class.java) - assertThat(communalContent?.get(2)) - .isInstanceOf(CommunalContentModel.Widget::class.java) - assertThat(communalContent?.get(3)) - .isInstanceOf(CommunalContentModel.Widget::class.java) + assertThat(umoContent?.size).isEqualTo(1) + assertThat(umoContent?.get(0)).isInstanceOf(CommunalContentModel.Umo::class.java) + assertThat(umoContent?.get(0)?.key).isEqualTo(CommunalContentModel.UMO_KEY) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java index b16c3520d978..d246f0e49e1c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java @@ -910,6 +910,20 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { assertATMSAndKeyguardViewMediatorStatesMatch(); } + @Test + @TestableLooper.RunWithLooper(setAsMainLooper = true) + public void testStartKeyguardExitAnimation_whenNotInteractive_doesShowAndUpdatesWM() { + // If the exit animation was triggered but the device became non-interactive, make sure + // relock happens + when(mPowerManager.isInteractive()).thenReturn(false); + + startMockKeyguardExitAnimation(); + cancelMockKeyguardExitAnimation(); + + verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null); + assertATMSAndKeyguardViewMediatorStatesMatch(); + } + /** * Interactions with the ActivityTaskManagerService and others are posted to an executor that * doesn't use the testable looper. Use this method to ensure those are run as well. diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 8d9bc751fbc9..0b148d14a43f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -45,6 +45,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository @@ -223,11 +224,13 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { alternateBouncerInteractor = AlternateBouncerInteractor( bouncerRepository = bouncerRepository, + fingerprintPropertyRepository = FakeFingerprintPropertyRepository(), biometricSettingsRepository = biometricSettingsRepository, systemClock = mock(SystemClock::class.java), keyguardStateController = FakeKeyguardStateController(), statusBarStateController = mock(StatusBarStateController::class.java), keyguardUpdateMonitor = keyguardUpdateMonitor, + scope = testScope.backgroundScope, ) displayRepository = FakeDisplayRepository() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt index e45f56a44b67..f2de8caef176 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt @@ -30,6 +30,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FaceSensorInfo import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.biometrics.shared.model.LockoutMode import com.android.systemui.biometrics.shared.model.SensorStrength import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository @@ -153,9 +154,11 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { mock(StatusBarStateController::class.java), mock(KeyguardStateController::class.java), bouncerRepository, + FakeFingerprintPropertyRepository(), fakeBiometricSettingsRepository, FakeSystemClock(), keyguardUpdateMonitor, + testScope.backgroundScope, ), keyguardTransitionInteractor, featureFlags, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt index f9362a773fc5..91e17059bb3d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt @@ -153,9 +153,11 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { statusBarStateController = mock(), keyguardStateController = mock(), bouncerRepository, + FakeFingerprintPropertyRepository(), biometricSettingsRepository, FakeSystemClock(), keyguardUpdateMonitor, + scope = testScope.backgroundScope, ), testScope.backgroundScope, mockedContext, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt index 76c258935727..15a17827a603 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt @@ -40,6 +40,7 @@ import com.android.systemui.keyguard.ui.view.layout.sections.DefaultStatusViewSe import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines import com.android.systemui.util.mockito.whenever +import java.util.Optional import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -48,7 +49,6 @@ import org.mockito.Mockito.mock import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -import java.util.Optional @RunWith(AndroidTestingRunner::class) @RunWithLooper(setAsMainLooper = true) @@ -59,8 +59,7 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() { @Mock private lateinit var defaultIndicationAreaSection: DefaultIndicationAreaSection @Mock private lateinit var mDefaultDeviceEntryIconSection: DefaultDeviceEntryIconSection @Mock private lateinit var defaultShortcutsSection: DefaultShortcutsSection - @Mock - private lateinit var defaultAmbientIndicationAreaSection: Optional<KeyguardSection> + @Mock private lateinit var defaultAmbientIndicationAreaSection: Optional<KeyguardSection> @Mock private lateinit var defaultSettingsPopupMenuSection: DefaultSettingsPopupMenuSection @Mock private lateinit var defaultStatusViewSection: DefaultStatusViewSection @Mock private lateinit var defaultStatusBarViewSection: DefaultStatusBarSection @@ -118,6 +117,13 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() { } @Test + fun deviceEntryIconIsOnTop() { + val constraintLayout = ConstraintLayout(context, null) + underTest.replaceViews(null, constraintLayout) + underTest.sections.forEach { verify(it)?.addViews(constraintLayout) } + } + + @Test fun applyConstraints() { val cs = ConstraintSet() underTest.applyConstraints(cs) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSectionTest.kt index a010ea966665..d9760456bcef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSectionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntryIconSectionTest.kt @@ -30,14 +30,17 @@ import com.android.systemui.biometrics.AuthController import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryBackgroundViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryForegroundViewModel import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryIconViewModel import com.android.systemui.plugins.FalsingManager import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView +import com.android.systemui.statusbar.NotificationShadeWindowController import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -81,6 +84,9 @@ class DefaultDeviceEntryIconSectionTest : SysuiTestCase() { { mock(DeviceEntryForegroundViewModel::class.java) }, { mock(DeviceEntryBackgroundViewModel::class.java) }, { falsingManager }, + { mock(AlternateBouncerViewModel::class.java) }, + { mock(NotificationShadeWindowController::class.java) }, + TestScope().backgroundScope, ) } @@ -165,4 +171,21 @@ class DefaultDeviceEntryIconSectionTest : SysuiTestCase() { assertThat(constraint.layout.topMargin).isEqualTo(5) assertThat(constraint.layout.startMargin).isEqualTo(4) } + + @Test + fun deviceEntryIconViewIsAboveAlternateBouncerView() { + mSetFlagsRule.enableFlags(AConfigFlags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR) + + val constraintLayout = ConstraintLayout(context, null) + underTest.addViews(constraintLayout) + assertThat(constraintLayout.childCount).isGreaterThan(0) + val deviceEntryIconView = constraintLayout.getViewById(R.id.device_entry_icon_view) + val alternateBouncerView = constraintLayout.getViewById(R.id.alternate_bouncer) + assertThat(deviceEntryIconView).isNotNull() + assertThat(alternateBouncerView).isNotNull() + + // device entry icon is above the alternate bouncer + assertThat(constraintLayout.indexOfChild(deviceEntryIconView)) + .isGreaterThan(constraintLayout.indexOfChild(alternateBouncerView)) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt index d3019f100774..a838684a4f41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt @@ -22,6 +22,7 @@ package com.android.systemui.keyguard.ui.viewmodel import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.Flags as AConfigFlags +import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION import com.android.systemui.SysUITestComponent import com.android.systemui.SysUITestModule import com.android.systemui.SysuiTestCase @@ -347,10 +348,7 @@ class KeyguardRootViewModelTestWithFakes : SysuiTestCase() { .create( test = this, featureFlags = - FakeFeatureFlagsClassicModule { - setDefault(Flags.NEW_AOD_TRANSITION) - set(Flags.FACE_AUTH_REFACTOR, true) - }, + FakeFeatureFlagsClassicModule { set(Flags.FACE_AUTH_REFACTOR, true) }, mocks = TestMocksModule( dozeParameters = dozeParams, @@ -363,6 +361,11 @@ class KeyguardRootViewModelTestWithFakes : SysuiTestCase() { block() } + @Before + fun before() { + mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION) + } + @Test fun iconContainer_isNotVisible_notOnKeyguard_dontShowAodIconsWhenShade() = runTest { val isVisible by collectLastValue(underTest.isNotifIconContainerVisible) diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt index 0b3bc9daa8b7..d07836d3abce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt @@ -94,6 +94,8 @@ class LockscreenSceneViewModelTest : SysuiTestCase() { KeyguardLongPressViewModel( interactor = mock(), ), + keyguardRoot = utils.keyguardRootViewModel(), + notifications = utils.notificationsPlaceholderViewModel(), ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt index ef129c85ed37..5c325ae67369 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt @@ -101,6 +101,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { ), shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, + notifications = utils.notificationsPlaceholderViewModel(), ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index 6a054cd9aff7..c3294ff2e26c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -152,6 +152,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { KeyguardLongPressViewModel( interactor = mock(), ), + keyguardRoot = utils.keyguardRootViewModel(), + notifications = utils.notificationsPlaceholderViewModel(), ) private val mobileIconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock()) @@ -237,6 +239,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { deviceEntryInteractor = deviceEntryInteractor, shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, + notifications = utils.notificationsPlaceholderViewModel(), ) utils.deviceEntryRepository.setUnlocked(false) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt index 0d3b2b372610..e2640af136a7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt @@ -101,6 +101,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() { deviceEntryInteractor = deviceEntryInteractor, shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, + notifications = utils.notificationsPlaceholderViewModel(), ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt index ea7c06865001..ffde6015c127 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/DragDownHelperTest.kt @@ -27,6 +27,7 @@ import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingOb import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.util.mockito.mock +import com.android.systemui.shade.data.repository.FakeShadeRepository import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -61,6 +62,7 @@ class DragDownHelperTest : SysuiTestCase() { falsingCollector, dragDownloadCallback, naturalScrollingSettingObserver, + FakeShadeRepository(), mContext, ).also { it.expandCallback = expandCallback diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt index 68761ef8139d..10d4c627bc4a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.icon.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION import com.android.systemui.SysUITestComponent import com.android.systemui.SysUITestModule import com.android.systemui.SysuiTestCase @@ -94,7 +95,6 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { FakeFeatureFlagsClassicModule { setDefault(Flags.FACE_AUTH_REFACTOR) set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) - setDefault(Flags.NEW_AOD_TRANSITION) }, mocks = TestMocksModule( @@ -115,6 +115,7 @@ class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { lastSleepReason = WakeSleepReason.OTHER, ) } + mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt index acc5cea0c8f9..1c7fd565c289 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.interruption import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest +import com.android.systemui.Flags import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE @@ -35,6 +36,10 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidTestingRunner::class) class NotificationInterruptStateProviderWrapperTest : VisualInterruptionDecisionProviderTestBase() { + init { + setFlagsRule.disableFlags(Flags.FLAG_VISUAL_INTERRUPTIONS_REFACTOR) + } + override val provider by lazy { NotificationInterruptStateProviderWrapper( NotificationInterruptStateProviderImpl( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt index 9e7df5f4a9f5..df6f0d716577 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.interruption import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest +import com.android.systemui.Flags import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK @@ -28,6 +29,10 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidTestingRunner::class) class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionProviderTestBase() { + init { + setFlagsRule.enableFlags(Flags.FLAG_VISUAL_INTERRUPTIONS_REFACTOR) + } + override val provider by lazy { VisualInterruptionDecisionProviderImpl( ambientDisplayConfiguration, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt index 5dcb6c9e9527..a3b7e8c8ca0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt @@ -44,6 +44,7 @@ import android.graphics.drawable.Icon import android.hardware.display.FakeAmbientDisplayConfiguration import android.os.Looper import android.os.PowerManager +import android.platform.test.flag.junit.SetFlagsRule import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED import android.provider.Settings.Global.HEADS_UP_OFF import android.provider.Settings.Global.HEADS_UP_ON @@ -83,10 +84,15 @@ import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.junit.Assert.assertEquals import org.junit.Before +import org.junit.Rule import org.junit.Test import org.mockito.Mockito.`when` as whenever abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { + @JvmField + @Rule + val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT) + private val fakeLogBuffer = LogBuffer( name = "FakeLog", diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index e91d6d724a73..ba5ba2c31a42 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.stack; import static android.view.View.GONE; import static android.view.WindowInsets.Type.ime; +import static com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE; import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.RUBBER_BAND_FACTOR_NORMAL; @@ -162,7 +163,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { // in the constructor. mFeatureFlags.setDefault(Flags.SENSITIVE_REVEAL_ANIM); mFeatureFlags.setDefault(Flags.ANIMATED_NOTIFICATION_SHADE_INSETS); - mFeatureFlags.setDefault(Flags.NEW_AOD_TRANSITION); + mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION); mFeatureFlags.setDefault(Flags.UNCLEARED_TRANSIENT_HUN_FIX); // Inject dependencies before initializing the layout diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index 9c70c82cfa26..3d7cff44322b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -253,8 +253,9 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { // Start on lockscreen showLockscreen() - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top = 1f, bottom = 2f) + ) assertThat(position) .isEqualTo(SharedNotificationContainerPosition(top = 1f, bottom = 2f)) @@ -273,8 +274,9 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { // Start on lockscreen showLockscreen() - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top = 1f, bottom = 2f) + ) runCurrent() // Top should be overridden to 0f @@ -327,8 +329,9 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { overrideResource(R.bool.config_use_split_notification_shade, false) configurationRepository.onAnyConfigurationChange() - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top = 1f, bottom = 2f) + ) assertThat(maxNotifications).isEqualTo(10) @@ -349,8 +352,9 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { overrideResource(R.bool.config_use_split_notification_shade, false) configurationRepository.onAnyConfigurationChange() - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top = 1f, bottom = 2f) + ) assertThat(maxNotifications).isEqualTo(10) @@ -383,8 +387,9 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { overrideResource(R.bool.config_use_split_notification_shade, false) configurationRepository.onAnyConfigurationChange() - keyguardInteractor.sharedNotificationContainerPosition.value = + keyguardInteractor.setSharedNotificationContainerPosition( SharedNotificationContainerPosition(top = 1f, bottom = 2f) + ) // -1 means No Limit assertThat(maxNotifications).isEqualTo(-1) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 6570724523bc..4b1c7e8faa38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -16,23 +16,18 @@ package com.android.systemui.statusbar.phone; -import static android.app.NotificationManager.IMPORTANCE_HIGH; -import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED; import static android.provider.Settings.Global.HEADS_UP_ON; +import static com.android.systemui.Flags.FLAG_LIGHT_REVEAL_MIGRATION; import static com.android.systemui.statusbar.StatusBarState.KEYGUARD; import static com.android.systemui.statusbar.StatusBarState.SHADE; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; - import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; @@ -48,8 +43,6 @@ import static java.util.Collections.emptySet; import android.app.ActivityManager; import android.app.IWallpaperManager; -import android.app.Notification; -import android.app.NotificationChannel; import android.app.WallpaperManager; import android.app.trust.TrustManager; import android.content.BroadcastReceiver; @@ -157,13 +150,13 @@ import com.android.systemui.statusbar.notification.NotificationActivityStarter; import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorControllerProvider; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore; -import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.init.NotificationsController; import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptLogger; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; @@ -218,7 +211,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { private CentralSurfacesImpl mCentralSurfaces; private FakeMetricsLogger mMetricsLogger; private PowerManager mPowerManager; - private TestableNotificationInterruptStateProviderImpl mNotificationInterruptStateProvider; + private VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider; @Mock private NotificationsController mNotificationsController; @Mock private LightBarController mLightBarController; @@ -349,7 +342,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFeatureFlags.set(Flags.WM_SHADE_ALLOW_BACK_GESTURE, true); // For the Shade to animate during the Back gesture, we must enable the animation flag. mFeatureFlags.set(Flags.WM_SHADE_ANIMATE_BACK_GESTURE, true); - mFeatureFlags.set(Flags.LIGHT_REVEAL_MIGRATION, true); + mSetFlagsRule.enableFlags(FLAG_LIGHT_REVEAL_MIGRATION); // Turn AOD on and toggle feature flag for jank fixes mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true); when(mDozeParameters.getAlwaysOn()).thenReturn(true); @@ -361,24 +354,25 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFakeGlobalSettings.putInt(HEADS_UP_NOTIFICATIONS_ENABLED, HEADS_UP_ON); - mNotificationInterruptStateProvider = - new TestableNotificationInterruptStateProviderImpl( - mPowerManager, - mAmbientDisplayConfiguration, - mStatusBarStateController, - mKeyguardStateController, - mBatteryController, - mHeadsUpManager, - mock(NotificationInterruptLogger.class), - new Handler(TestableLooper.get(this).getLooper()), - mock(NotifPipelineFlags.class), - mock(KeyguardNotificationVisibilityProvider.class), - mock(UiEventLogger.class), - mUserTracker, - mDeviceProvisionedController, - mFakeSystemClock, - mFakeGlobalSettings, - mFakeEventLog); + mVisualInterruptionDecisionProvider = + new NotificationInterruptStateProviderWrapper( + new TestableNotificationInterruptStateProviderImpl( + mPowerManager, + mAmbientDisplayConfiguration, + mStatusBarStateController, + mKeyguardStateController, + mBatteryController, + mHeadsUpManager, + mock(NotificationInterruptLogger.class), + new Handler(TestableLooper.get(this).getLooper()), + mock(NotifPipelineFlags.class), + mock(KeyguardNotificationVisibilityProvider.class), + mock(UiEventLogger.class), + mUserTracker, + mDeviceProvisionedController, + mFakeSystemClock, + mFakeGlobalSettings, + mFakeEventLog)); mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class)); mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class)); @@ -481,7 +475,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { new FalsingCollectorFake(), mBroadcastDispatcher, mNotificationGutsManager, - mNotificationInterruptStateProvider, + mVisualInterruptionDecisionProvider, new ShadeExpansionStateManager(), mKeyguardViewMediator, new DisplayMetrics(), @@ -692,92 +686,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { } @Test - public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception { - when(mPowerManager.isScreenOn()).thenReturn(true); - when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false); - when(mStatusBarStateController.isDreaming()).thenReturn(false); - - Notification n = new Notification.Builder(getContext(), "a") - .setGroup("a") - .setGroupSummary(true) - .setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .setImportance(IMPORTANCE_HIGH) - .build(); - - assertTrue(mNotificationInterruptStateProvider.shouldHeadsUp(entry)); - } - - @Test - public void testShouldHeadsUp_suppressedGroupSummary() throws Exception { - when(mPowerManager.isScreenOn()).thenReturn(true); - when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false); - when(mStatusBarStateController.isDreaming()).thenReturn(false); - - Notification n = new Notification.Builder(getContext(), "a") - .setGroup("a") - .setGroupSummary(true) - .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN) - .build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .setImportance(IMPORTANCE_HIGH) - .build(); - - assertFalse(mNotificationInterruptStateProvider.shouldHeadsUp(entry)); - } - - @Test - public void testShouldHeadsUp_suppressedHeadsUp() throws Exception { - when(mPowerManager.isScreenOn()).thenReturn(true); - when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false); - when(mStatusBarStateController.isDreaming()).thenReturn(false); - - Notification n = new Notification.Builder(getContext(), "a").build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setChannel(new NotificationChannel("id", null, IMPORTANCE_HIGH)) - .setNotification(n) - .setImportance(IMPORTANCE_HIGH) - .setSuppressedVisualEffects(SUPPRESSED_EFFECT_PEEK) - .build(); - - assertFalse(mNotificationInterruptStateProvider.shouldHeadsUp(entry)); - } - - @Test - public void testShouldHeadsUp_noSuppressedHeadsUp() throws Exception { - when(mPowerManager.isScreenOn()).thenReturn(true); - when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false); - when(mStatusBarStateController.isDreaming()).thenReturn(false); - - Notification n = new Notification.Builder(getContext(), "a").build(); - - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .setImportance(IMPORTANCE_HIGH) - .build(); - - assertTrue(mNotificationInterruptStateProvider.shouldHeadsUp(entry)); - } - - @Test public void testDump_DoesNotCrash() { mCentralSurfaces.dump(new PrintWriter(new ByteArrayOutputStream()), null); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 15c09b53938f..4827c92ce452 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -1185,14 +1185,11 @@ public class ScrimControllerTest extends SysuiTestCase { } @Test - public void testScrimFocus() { - mScrimController.transitionTo(ScrimState.AOD); - assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable()); - assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable()); - - mScrimController.transitionTo(ScrimState.KEYGUARD); - Assert.assertTrue("Should be focusable on keyguard", mScrimBehind.isFocusable()); - Assert.assertTrue("Should be focusable on keyguard", mScrimInFront.isFocusable()); + public void testScrimsAreNotFocusable() { + assertFalse("Behind scrim should not be focusable", mScrimBehind.isFocusable()); + assertFalse("Front scrim should not be focusable", mScrimInFront.isFocusable()); + assertFalse("Notifications scrim should not be focusable", + mNotificationsScrim.isFocusable()); } @Test @@ -1263,14 +1260,6 @@ public class ScrimControllerTest extends SysuiTestCase { } @Test - public void testViewsDontHaveFocusHighlight() { - assertFalse("Scrim shouldn't have focus highlight", - mScrimInFront.getDefaultFocusHighlightEnabled()); - assertFalse("Scrim shouldn't have focus highlight", - mScrimBehind.getDefaultFocusHighlightEnabled()); - } - - @Test public void testIsLowPowerMode() { HashSet<ScrimState> lowPowerModeStates = new HashSet<>(Arrays.asList( ScrimState.OFF, ScrimState.AOD, ScrimState.PULSING)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index d1423e10ce79..6cc4e44116ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -88,7 +88,6 @@ import com.android.systemui.statusbar.notification.collection.provider.LaunchFul import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.data.repository.NotificationLaunchAnimationRepository; import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor; -import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; @@ -139,8 +138,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { @Mock private KeyguardStateController mKeyguardStateController; @Mock - private NotificationInterruptStateProvider mNotificationInterruptStateProvider; - @Mock private Handler mHandler; @Mock private BubblesManager mBubblesManager; @@ -246,7 +243,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardStateController, - mNotificationInterruptStateProvider, mock(LockPatternUtils.class), mock(StatusBarRemoteInputCallback.class), mActivityIntentHelper, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 53c621d24601..bbdc9ced57ee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -16,22 +16,28 @@ package com.android.systemui.statusbar.phone; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK; +import static com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.PendingIntent; import android.app.StatusBarManager; +import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; -import com.android.internal.logging.testing.FakeMetricsLogger; +import com.android.systemui.Flags; import com.android.systemui.InitController; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ActivityStarter; @@ -55,7 +61,10 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource; import com.android.systemui.statusbar.notification.domain.interactor.NotificationAlertsInteractor; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionCondition; import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionFilter; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; @@ -64,10 +73,14 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import java.util.List; +import java.util.Set; + @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper() @@ -76,18 +89,23 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { private final VisualInterruptionDecisionProvider mVisualInterruptionDecisionProvider = mock(VisualInterruptionDecisionProvider.class); private NotificationInterruptSuppressor mInterruptSuppressor; + private VisualInterruptionCondition mAlertsDisabledCondition; + private VisualInterruptionCondition mVrModeCondition; + private VisualInterruptionFilter mNeedsRedactionFilter; + private VisualInterruptionCondition mPanelsDisabledCondition; private CommandQueue mCommandQueue; - private FakeMetricsLogger mMetricsLogger; private final ShadeController mShadeController = mock(ShadeController.class); private final NotificationAlertsInteractor mNotificationAlertsInteractor = mock(NotificationAlertsInteractor.class); private final KeyguardStateController mKeyguardStateController = mock(KeyguardStateController.class); - private final InitController mInitController = new InitController(); + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule( + SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT); @Before public void setup() { - mMetricsLogger = new FakeMetricsLogger(); mCommandQueue = new CommandQueue(mContext, new FakeDisplayTracker(mContext)); mDependency.injectTestDependency(StatusBarStateController.class, mock(SysuiStatusBarStateController.class)); @@ -95,15 +113,182 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mDependency.injectMockDependency(NotificationRemoteInputManager.Callback.class); mDependency.injectMockDependency(NotificationShadeWindowController.class); - NotificationShadeWindowView notificationShadeWindowView = + when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(true); + } + + @Test + public void testInit_refactorDisabled() { + ensureRefactorDisabledState(); + } + + @Test + public void testInit_refactorEnabled() { + ensureRefactorEnabledState(); + } + + @Test + public void testNoSuppressHeadsUp_default_refactorDisabled() { + ensureRefactorDisabledState(); + + assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry())); + } + + @Test + public void testNoSuppressHeadsUp_default_refactorEnabled() { + ensureRefactorEnabledState(); + + assertFalse(mAlertsDisabledCondition.shouldSuppress()); + assertFalse(mVrModeCondition.shouldSuppress()); + assertFalse(mNeedsRedactionFilter.shouldSuppress(createNotificationEntry())); + assertFalse(mAlertsDisabledCondition.shouldSuppress()); + } + + @Test + public void testSuppressHeadsUp_disabledStatusBar_refactorDisabled() { + ensureRefactorDisabledState(); + + mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0, + false /* animate */); + TestableLooper.get(this).processAllMessages(); + + assertTrue("The panel should suppress heads up while disabled", + mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry())); + } + + @Test + public void testSuppressHeadsUp_disabledStatusBar_refactorEnabled() { + ensureRefactorEnabledState(); + + mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0, + false /* animate */); + TestableLooper.get(this).processAllMessages(); + + assertTrue("The panel should suppress heads up while disabled", + mPanelsDisabledCondition.shouldSuppress()); + } + + @Test + public void testSuppressHeadsUp_disabledNotificationShade_refactorDisabled() { + ensureRefactorDisabledState(); + + mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, + false /* animate */); + TestableLooper.get(this).processAllMessages(); + + assertTrue("The panel should suppress interruptions while notification shade disabled", + mInterruptSuppressor.suppressAwakeHeadsUp(createNotificationEntry())); + } + + @Test + public void testSuppressHeadsUp_disabledNotificationShade_refactorEnabled() { + ensureRefactorEnabledState(); + + mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, + false /* animate */); + TestableLooper.get(this).processAllMessages(); + + assertTrue("The panel should suppress interruptions while notification shade disabled", + mPanelsDisabledCondition.shouldSuppress()); + } + + @Test + public void testPanelsDisabledConditionSuppressesPeek() { + ensureRefactorEnabledState(); + + final Set<VisualInterruptionType> types = mPanelsDisabledCondition.getTypes(); + assertTrue(types.contains(PEEK)); + assertFalse(types.contains(PULSE)); + assertFalse(types.contains(BUBBLE)); + } + + @Test + public void testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorDisabled() { + ensureRefactorDisabledState(); + + when(mKeyguardStateController.isShowing()).thenReturn(true); + when(mKeyguardStateController.isOccluded()).thenReturn(false); + + assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(createFsiNotificationEntry())); + } + + @Test + public void testNoSuppressHeadsUp_FSI_nonOccludedKeyguard_refactorEnabled() { + ensureRefactorEnabledState(); + + when(mKeyguardStateController.isShowing()).thenReturn(true); + when(mKeyguardStateController.isOccluded()).thenReturn(false); + + assertFalse(mNeedsRedactionFilter.shouldSuppress(createFsiNotificationEntry())); + + final Set<VisualInterruptionType> types = mNeedsRedactionFilter.getTypes(); + assertTrue(types.contains(PEEK)); + assertFalse(types.contains(PULSE)); + assertFalse(types.contains(BUBBLE)); + } + + @Test + public void testSuppressInterruptions_vrMode_refactorDisabled() { + ensureRefactorDisabledState(); + + mStatusBarNotificationPresenter.mVrMode = true; + + assertTrue("Vr mode should suppress interruptions", + mInterruptSuppressor.suppressAwakeInterruptions(createNotificationEntry())); + } + + @Test + public void testSuppressInterruptions_vrMode_refactorEnabled() { + ensureRefactorEnabledState(); + + mStatusBarNotificationPresenter.mVrMode = true; + + assertTrue("Vr mode should suppress interruptions", mVrModeCondition.shouldSuppress()); + + final Set<VisualInterruptionType> types = mVrModeCondition.getTypes(); + assertTrue(types.contains(PEEK)); + assertFalse(types.contains(PULSE)); + assertTrue(types.contains(BUBBLE)); + } + + @Test + public void testSuppressInterruptions_statusBarAlertsDisabled_refactorDisabled() { + ensureRefactorDisabledState(); + + when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false); + + assertTrue("When alerts aren't enabled, interruptions are suppressed", + mInterruptSuppressor.suppressInterruptions(createNotificationEntry())); + } + + @Test + public void testSuppressInterruptions_statusBarAlertsDisabled_refactorEnabled() { + ensureRefactorEnabledState(); + + when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false); + + assertTrue("When alerts aren't enabled, interruptions are suppressed", + mAlertsDisabledCondition.shouldSuppress()); + + final Set<VisualInterruptionType> types = mAlertsDisabledCondition.getTypes(); + assertTrue(types.contains(PEEK)); + assertTrue(types.contains(PULSE)); + assertTrue(types.contains(BUBBLE)); + } + + private void createPresenter() { + final ShadeViewController shadeViewController = mock(ShadeViewController.class); + + final NotificationShadeWindowView notificationShadeWindowView = mock(NotificationShadeWindowView.class); + when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources()); + NotificationStackScrollLayoutController stackScrollLayoutController = mock(NotificationStackScrollLayoutController.class); when(stackScrollLayoutController.getView()).thenReturn( mock(NotificationStackScrollLayout.class)); - when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources()); - ShadeViewController shadeViewController = mock(ShadeViewController.class); + final InitController initController = new InitController(); + mStatusBarNotificationPresenter = new StatusBarNotificationPresenter( mContext, shadeViewController, @@ -125,110 +310,76 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mock(NotifShadeEventSource.class), mock(NotificationMediaManager.class), mock(NotificationGutsManager.class), - mInitController, + initController, mVisualInterruptionDecisionProvider, mock(NotificationRemoteInputManager.class), mock(NotificationRemoteInputManager.Callback.class), mock(NotificationListContainer.class)); - mInitController.executePostInitTasks(); - ArgumentCaptor<NotificationInterruptSuppressor> suppressorCaptor = - ArgumentCaptor.forClass(NotificationInterruptSuppressor.class); - verify(mVisualInterruptionDecisionProvider).addLegacySuppressor(suppressorCaptor.capture()); - mInterruptSuppressor = suppressorCaptor.getValue(); + + initController.executePostInitTasks(); } - @Test - public void testNoSuppressHeadsUp_default() { - Notification n = new Notification.Builder(getContext(), "a").build(); - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .build(); + private void verifyAndCaptureSuppressors() { + mInterruptSuppressor = null; - assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(entry)); + final ArgumentCaptor<VisualInterruptionCondition> conditionCaptor = + ArgumentCaptor.forClass(VisualInterruptionCondition.class); + verify(mVisualInterruptionDecisionProvider, times(3)).addCondition( + conditionCaptor.capture()); + final List<VisualInterruptionCondition> conditions = conditionCaptor.getAllValues(); + mAlertsDisabledCondition = conditions.get(0); + mVrModeCondition = conditions.get(1); + mPanelsDisabledCondition = conditions.get(2); + + final ArgumentCaptor<VisualInterruptionFilter> needsRedactionFilterCaptor = + ArgumentCaptor.forClass(VisualInterruptionFilter.class); + verify(mVisualInterruptionDecisionProvider).addFilter(needsRedactionFilterCaptor.capture()); + mNeedsRedactionFilter = needsRedactionFilterCaptor.getValue(); } - @Test - public void testSuppressHeadsUp_disabledStatusBar() { - Notification n = new Notification.Builder(getContext(), "a").build(); - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .build(); - mCommandQueue.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_EXPAND, 0, - false /* animate */); - TestableLooper.get(this).processAllMessages(); + private void verifyAndCaptureLegacySuppressor() { + mAlertsDisabledCondition = null; + mVrModeCondition = null; + mNeedsRedactionFilter = null; + mPanelsDisabledCondition = null; - assertTrue("The panel should suppress heads up while disabled", - mInterruptSuppressor.suppressAwakeHeadsUp(entry)); + final ArgumentCaptor<NotificationInterruptSuppressor> suppressorCaptor = + ArgumentCaptor.forClass(NotificationInterruptSuppressor.class); + verify(mVisualInterruptionDecisionProvider).addLegacySuppressor(suppressorCaptor.capture()); + mInterruptSuppressor = suppressorCaptor.getValue(); } - @Test - public void testSuppressHeadsUp_disabledNotificationShade() { - Notification n = new Notification.Builder(getContext(), "a").build(); - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) - .build(); - mCommandQueue.disable(DEFAULT_DISPLAY, 0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, - false /* animate */); - TestableLooper.get(this).processAllMessages(); + private void ensureRefactorDisabledState() { + mSetFlagsRule.disableFlags(Flags.FLAG_VISUAL_INTERRUPTIONS_REFACTOR); + createPresenter(); + verifyAndCaptureLegacySuppressor(); + } - assertTrue("The panel should suppress interruptions while notification shade " - + "disabled", - mInterruptSuppressor.suppressAwakeHeadsUp(entry)); + private void ensureRefactorEnabledState() { + mSetFlagsRule.enableFlags(Flags.FLAG_VISUAL_INTERRUPTIONS_REFACTOR); + createPresenter(); + verifyAndCaptureSuppressors(); } - @Test - public void testNoSuppressHeadsUp_FSI_nonOccludedKeyguard() { - Notification n = new Notification.Builder(getContext(), "a") - .setFullScreenIntent(mock(PendingIntent.class), true) - .build(); - NotificationEntry entry = new NotificationEntryBuilder() + private NotificationEntry createNotificationEntry() { + return new NotificationEntryBuilder() .setPkg("a") .setOpPkg("a") .setTag("a") - .setNotification(n) + .setNotification(new Notification.Builder(getContext(), "a").build()) .build(); - - when(mKeyguardStateController.isShowing()).thenReturn(true); - when(mKeyguardStateController.isOccluded()).thenReturn(false); - assertFalse(mInterruptSuppressor.suppressAwakeHeadsUp(entry)); } - @Test - public void testSuppressInterruptions_vrMode() { - Notification n = new Notification.Builder(getContext(), "a").build(); - NotificationEntry entry = new NotificationEntryBuilder() - .setPkg("a") - .setOpPkg("a") - .setTag("a") - .setNotification(n) + private NotificationEntry createFsiNotificationEntry() { + final Notification notification = new Notification.Builder(getContext(), "a") + .setFullScreenIntent(mock(PendingIntent.class), true) .build(); - mStatusBarNotificationPresenter.mVrMode = true; - - assertTrue("Vr mode should suppress interruptions", - mInterruptSuppressor.suppressAwakeInterruptions(entry)); - } - @Test - public void testSuppressInterruptions_statusBarAlertsDisabled() { - Notification n = new Notification.Builder(getContext(), "a").build(); - NotificationEntry entry = new NotificationEntryBuilder() + return new NotificationEntryBuilder() .setPkg("a") .setOpPkg("a") .setTag("a") - .setNotification(n) + .setNotification(notification) .build(); - when(mNotificationAlertsInteractor.areNotificationAlertsEnabled()).thenReturn(false); - - assertTrue("When alerts aren't enabled, interruptions are suppressed", - mInterruptSuppressor.suppressInterruptions(entry)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt index e91b0c1a9a6d..1fb6e2c7a232 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt @@ -25,6 +25,8 @@ import android.telephony.TelephonyManager import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel @@ -68,6 +70,9 @@ import org.mockito.Mockito.verify class FullMobileConnectionRepositoryTest : SysuiTestCase() { private lateinit var underTest: FullMobileConnectionRepository + private val flags = + FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } + private val systemClock = FakeSystemClock() private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) @@ -690,6 +695,7 @@ class FullMobileConnectionRepositoryTest : SysuiTestCase() { testDispatcher, logger = mock(), tableLogBuffer, + flags, testScope.backgroundScope, ) whenever( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt index a90bd48a5bce..9d6f3156f83e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt @@ -35,7 +35,9 @@ import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback.DataActivityListener +import android.telephony.TelephonyCallback.DisplayInfoListener import android.telephony.TelephonyCallback.ServiceStateListener +import android.telephony.TelephonyDisplayInfo import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE import android.telephony.TelephonyManager @@ -65,6 +67,8 @@ import androidx.test.filters.SmallTest import com.android.settingslib.mobile.MobileMappings import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState @@ -111,6 +115,9 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { private lateinit var underTest: MobileConnectionRepositoryImpl private lateinit var connectionsRepo: FakeMobileConnectionsRepository + private val flags = + FakeFeatureFlagsClassic().also { it.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } + @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var logger: MobileInputLogger @@ -158,6 +165,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { testDispatcher, logger, tableLogger, + flags, testScope.backgroundScope, ) } @@ -610,8 +618,80 @@ class MobileConnectionRepositoryTest : SysuiTestCase() { } @Test - fun roaming_gsm_queriesServiceState() = + fun roaming_gsm_queriesDisplayInfo_viaDisplayInfo() = testScope.runTest { + // GIVEN flag is true + flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) + + // Re-create the repository, because the flag is read at init + underTest = + MobileConnectionRepositoryImpl( + SUB_1_ID, + context, + subscriptionModel, + DEFAULT_NAME_MODEL, + SEP, + connectivityManager, + telephonyManager, + systemUiCarrierConfig, + fakeBroadcastDispatcher, + mobileMappings, + testDispatcher, + logger, + tableLogger, + flags, + testScope.backgroundScope, + ) + + var latest: Boolean? = null + val job = underTest.isRoaming.onEach { latest = it }.launchIn(this) + + val cb = getTelephonyCallbackForType<DisplayInfoListener>() + + // CDMA roaming is off, GSM roaming is off + whenever(telephonyManager.cdmaEnhancedRoamingIndicatorDisplayNumber).thenReturn(ERI_OFF) + cb.onDisplayInfoChanged( + TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, false) + ) + + assertThat(latest).isFalse() + + // CDMA roaming is off, GSM roaming is on + cb.onDisplayInfoChanged( + TelephonyDisplayInfo(NETWORK_TYPE_LTE, NETWORK_TYPE_UNKNOWN, true) + ) + + assertThat(latest).isTrue() + + job.cancel() + } + + @Test + fun roaming_gsm_queriesDisplayInfo_viaServiceState() = + testScope.runTest { + // GIVEN flag is false + flags.set(ROAMING_INDICATOR_VIA_DISPLAY_INFO, false) + + // Re-create the repository, because the flag is read at init + underTest = + MobileConnectionRepositoryImpl( + SUB_1_ID, + context, + subscriptionModel, + DEFAULT_NAME_MODEL, + SEP, + connectivityManager, + telephonyManager, + systemUiCarrierConfig, + fakeBroadcastDispatcher, + mobileMappings, + testDispatcher, + logger, + tableLogger, + flags, + testScope.backgroundScope, + ) + var latest: Boolean? = null val job = underTest.isRoaming.onEach { latest = it }.launchIn(this) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt index 889f60a08766..2ab8c0a07e21 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt @@ -32,6 +32,8 @@ import android.telephony.TelephonyManager.NETWORK_TYPE_LTE import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.pipeline.mobile.data.MobileInputLogger import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState @@ -97,6 +99,9 @@ class MobileConnectionTelephonySmokeTests : SysuiTestCase() { private lateinit var underTest: MobileConnectionRepositoryImpl private lateinit var connectionsRepo: FakeMobileConnectionsRepository + private val flags = + FakeFeatureFlagsClassic().also { it.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } + @Mock private lateinit var connectivityManager: ConnectivityManager @Mock private lateinit var telephonyManager: TelephonyManager @Mock private lateinit var logger: MobileInputLogger @@ -139,6 +144,7 @@ class MobileConnectionTelephonySmokeTests : SysuiTestCase() { testDispatcher, logger, tableLogger, + flags, testScope.backgroundScope, ) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt index 03f300542a6f..07abd275d1ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt @@ -44,6 +44,8 @@ import com.android.settingslib.R import com.android.settingslib.mobile.MobileMappings import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBufferFactory import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository @@ -93,6 +95,9 @@ import org.mockito.MockitoAnnotations @TestableLooper.RunWithLooper class MobileConnectionsRepositoryTest : SysuiTestCase() { + private val flags = + FakeFeatureFlagsClassic().also { it.set(Flags.ROAMING_INDICATOR_VIA_DISPLAY_INFO, true) } + private lateinit var connectionFactory: MobileConnectionRepositoryImpl.Factory private lateinit var carrierMergedFactory: CarrierMergedConnectionRepository.Factory private lateinit var fullConnectionFactory: FullMobileConnectionRepository.Factory @@ -189,6 +194,7 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() { logger = logger, mobileMappingsProxy = mobileMappings, scope = testScope.backgroundScope, + flags = flags, carrierConfigRepository = carrierConfigRepository, ) carrierMergedFactory = diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt index cf815c27a0bf..ec04da7030b7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt @@ -50,10 +50,7 @@ object MobileTelephonyHelpers { } fun telephonyDisplayInfo(networkType: Int, overrideNetworkType: Int) = - mock<TelephonyDisplayInfo>().also { - whenever(it.networkType).thenReturn(networkType) - whenever(it.overrideNetworkType).thenReturn(overrideNetworkType) - } + TelephonyDisplayInfo(networkType, overrideNetworkType) inline fun <reified T> getTelephonyCallbackForType(mockTelephonyManager: TelephonyManager): T { val cbs = getTelephonyCallbacks(mockTelephonyManager).filterIsInstance<T>() diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index aa5f987b22a8..df7609c544a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -78,6 +78,7 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.Pair; import android.util.SparseArray; +import android.view.Display; import android.view.IWindowManager; import android.view.View; import android.view.ViewTreeObserver; @@ -337,6 +338,8 @@ public class BubblesTest extends SysuiTestCase { private NotifPipelineFlags mNotifPipelineFlags; @Mock private Icon mAppBubbleIcon; + @Mock + private Display mDefaultDisplay; private final SceneTestUtils mUtils = new SceneTestUtils(this); private final TestScope mTestScope = mUtils.getTestScope(); @@ -378,6 +381,7 @@ public class BubblesTest extends SysuiTestCase { when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); when(mNotificationShadeWindowView.getViewTreeObserver()) .thenReturn(mock(ViewTreeObserver.class)); + when(mWindowManager.getDefaultDisplay()).thenReturn(mDefaultDisplay); FakeDeviceProvisioningRepository deviceProvisioningRepository = diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastDispatcherKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastDispatcherKosmos.kt new file mode 100644 index 000000000000..7207948412b4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastDispatcherKosmos.kt @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.broadcast + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.util.mockito.mock + +val Kosmos.broadcastDispatcher by + Kosmos.Fixture { + FakeBroadcastDispatcher( + context = mock(), + mainExecutor = mock(), + broadcastRunningLooper = mock(), + broadcastRunningExecutor = mock(), + dumpManager = mock(), + logger = mock(), + userTracker = mock(), + shouldFailOnLeakedReceiver = false + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt index 3aee889d55f4..b27926c8ba50 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorFactory.kt @@ -65,7 +65,6 @@ object CommunalInteractorFactory { widgetRepository, mediaRepository, smartspaceRepository, - withDeps.communalTutorialInteractor, appWidgetHost, editWidgetsActivityStarter, ), diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsKosmos.kt new file mode 100644 index 000000000000..a78076338c79 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FeatureFlagsKosmos.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.flags + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.featureFlags by Kosmos.Fixture { FakeFeatureFlagsClassic() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt index d3744d55c55d..4068e408f0bd 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt @@ -167,6 +167,10 @@ class FakeKeyguardRepository @Inject constructor() : KeyguardRepository { _isKeyguardOccluded.value = isOccluded } + fun setKeyguardUnlocked(isUnlocked: Boolean) { + _isKeyguardUnlocked.value = isUnlocked + } + override fun setIsDozing(isDozing: Boolean) { _isDozing.value = isDozing } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt index fc34903e8a1d..6c2ce7139375 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorFactory.kt @@ -20,6 +20,7 @@ import android.content.Context import android.os.Handler import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor @@ -86,9 +87,11 @@ object KeyguardDismissInteractorFactory { mock(StatusBarStateController::class.java), mock(KeyguardStateController::class.java), bouncerRepository, + FakeFingerprintPropertyRepository(), FakeBiometricSettingsRepository(), FakeSystemClock(), keyguardUpdateMonitor, + testScope.backgroundScope, ) val powerInteractorWithDeps = PowerInteractorFactory.create( diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt index cc843b536756..b05915c4f678 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt @@ -1,8 +1,16 @@ package com.android.systemui.kosmos +import android.content.Context +import android.os.UserManager import com.android.systemui.kosmos.Kosmos.Fixture +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope +import org.mockito.Mockito -val Kosmos.testDispatcher by Fixture { StandardTestDispatcher() } -val Kosmos.testScope by Fixture { TestScope(testDispatcher) } +var Kosmos.testDispatcher by Fixture { StandardTestDispatcher() } +var Kosmos.testScope by Fixture { TestScope(testDispatcher) } +var Kosmos.context by Fixture<Context>() +var Kosmos.lifecycleScope by Fixture<CoroutineScope>() + +val Kosmos.userManager by Fixture { Mockito.mock(UserManager::class.java) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index 29e73b548b0b..80c38b2d228c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -63,7 +63,9 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeTrustRepository import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.data.repository.TrustRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope @@ -78,6 +80,9 @@ import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.data.repository.FakeShadeRepository +import com.android.systemui.statusbar.notification.stack.data.repository.NotificationStackAppearanceRepository +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor +import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository @@ -117,6 +122,7 @@ class SceneTestUtils( FakeFeatureFlagsClassic().apply { set(Flags.FACE_AUTH_REFACTOR, false) set(Flags.FULL_SCREEN_USER_SWITCHER, false) + set(Flags.NSSL_DEBUG_LINES, false) } val sceneContainerFlags = FakeSceneContainerFlags().apply { enabled = true } val deviceEntryRepository: FakeDeviceEntryRepository by lazy { FakeDeviceEntryRepository() } @@ -258,12 +264,14 @@ class SceneTestUtils( fun bouncerInteractor( authenticationInteractor: AuthenticationInteractor, + keyguardFaceAuthInteractor: KeyguardFaceAuthInteractor = mock(), ): BouncerInteractor { return BouncerInteractor( applicationScope = applicationScope(), applicationContext = context, repository = bouncerRepository, authenticationInteractor = authenticationInteractor, + keyguardFaceAuthInteractor = keyguardFaceAuthInteractor, flags = sceneContainerFlags, falsingInteractor = falsingInteractor(), powerInteractor = powerInteractor(), @@ -271,6 +279,19 @@ class SceneTestUtils( ) } + fun keyguardRootViewModel(): KeyguardRootViewModel = mock() + + fun notificationsPlaceholderViewModel(): NotificationsPlaceholderViewModel { + return NotificationsPlaceholderViewModel( + interactor = + NotificationStackAppearanceInteractor( + repository = NotificationStackAppearanceRepository(), + ), + flags = sceneContainerFlags, + featureFlags = featureFlags, + ) + } + fun bouncerViewModel( bouncerInteractor: BouncerInteractor, authenticationInteractor: AuthenticationInteractor, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserRepositoryKosmos.kt new file mode 100644 index 000000000000..8bce9b6d461d --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/UserRepositoryKosmos.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.data.repository + +import com.android.systemui.kosmos.Kosmos + +val Kosmos.userRepository by Kosmos.Fixture { FakeUserRepository() } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/GuestUserInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/GuestUserInteractorKosmos.kt new file mode 100644 index 000000000000..e69570433d43 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/GuestUserInteractorKosmos.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.context +import com.android.systemui.kosmos.lifecycleScope +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.userManager +import com.android.systemui.user.data.repository.userRepository +import com.android.systemui.util.mockito.mock + +val Kosmos.guestUserInteractor by + Kosmos.Fixture { + GuestUserInteractor( + applicationContext = context, + applicationScope = lifecycleScope, + mainDispatcher = testDispatcher, + backgroundDispatcher = testDispatcher, + manager = userManager, + deviceProvisionedController = mock(), + repository = userRepository, + devicePolicyManager = mock(), + refreshUsersScheduler = refreshUsersScheduler, + uiEventLogger = mock(), + resumeSessionReceiver = mock(), + resetOrExitSessionReceiver = mock(), + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerKosmos.kt new file mode 100644 index 000000000000..87a2fe0249e3 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerKosmos.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.domain.interactor + +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.lifecycleScope +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.user.data.repository.userRepository + +val Kosmos.refreshUsersScheduler by + Kosmos.Fixture { + RefreshUsersScheduler( + applicationScope = lifecycleScope, + mainDispatcher = testDispatcher, + repository = userRepository, + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorKosmos.kt new file mode 100644 index 000000000000..6d6b2683a7ea --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorKosmos.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.user.domain.interactor + +import com.android.systemui.broadcast.broadcastDispatcher +import com.android.systemui.flags.featureFlags +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.context +import com.android.systemui.kosmos.lifecycleScope +import com.android.systemui.kosmos.testDispatcher +import com.android.systemui.kosmos.userManager +import com.android.systemui.telephony.data.repository.FakeTelephonyRepository +import com.android.systemui.telephony.domain.interactor.TelephonyInteractor +import com.android.systemui.user.data.repository.userRepository +import com.android.systemui.util.mockito.mock + +val Kosmos.userSwitcherInteractor by + Kosmos.Fixture { + UserSwitcherInteractor( + applicationContext = context, + repository = userRepository, + activityStarter = mock(), + keyguardInteractor = + KeyguardInteractorFactory.create(featureFlags = featureFlags).keyguardInteractor, + featureFlags = featureFlags, + manager = userManager, + headlessSystemUserMode = mock(), + applicationScope = lifecycleScope, + telephonyInteractor = + TelephonyInteractor( + repository = FakeTelephonyRepository(), + ), + broadcastDispatcher = broadcastDispatcher, + keyguardUpdateMonitor = mock(), + backgroundDispatcher = testDispatcher, + activityManager = mock(), + refreshUsersScheduler = refreshUsersScheduler, + guestUserInteractor = guestUserInteractor, + uiEventLogger = mock(), + userRestrictionChecker = mock() + ) + } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java index db5eaffee76b..beabaf5f5954 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java @@ -38,7 +38,9 @@ public class FakeGlobalSettings implements GlobalSettings { @Override public ContentResolver getContentResolver() { - return null; + throw new UnsupportedOperationException( + "GlobalSettings.getContentResolver is not implemented, but you may find " + + "GlobalSettings.registerContentObserver helpful instead."); } @Override diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index b9e34ee97f21..3f46ab859bf9 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -25,12 +25,32 @@ java_library { } java_library { - name: "ravenwood-junit", - srcs: ["junit-src/**/*.java"], + name: "ravenwood-junit-impl", + srcs: [ + "junit-src/**/*.java", + "junit-impl-src/**/*.java", + ], libs: [ "framework-minus-apex.ravenwood", "junit", ], + visibility: ["//frameworks/base"], +} + +// Carefully compiles against only test_current to support tests that +// want to verify they're unbundled. The "impl" library above is what +// ships inside the Ravenwood environment to actually drive any API +// access to implementation details. +java_library { + name: "ravenwood-junit", + srcs: [ + "junit-src/**/*.java", + "junit-stub-src/**/*.java", + ], + sdk_version: "test_current", + libs: [ + "junit", + ], visibility: ["//visibility:public"], } diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/framework-minus-apex-ravenwood-policies.txt index aa2d470d7d9c..28639d4960a4 100644 --- a/ravenwood/framework-minus-apex-ravenwood-policies.txt +++ b/ravenwood/framework-minus-apex-ravenwood-policies.txt @@ -129,7 +129,3 @@ class android.net.UriCodec stubclass # Context: just enough to support wrapper, no further functionality class android.content.Context stub method <init> ()V stub - -# Text -class android.text.TextUtils stub - method isEmpty (Ljava/lang/CharSequence;)Z stub diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java new file mode 100644 index 000000000000..1caef26d50eb --- /dev/null +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.platform.test.ravenwood; + +public class RavenwoodRuleImpl { + public static void init(RavenwoodRule rule) { + android.os.Process.init$ravenwood(rule.mUid, rule.mPid); + android.os.Binder.init$ravenwood(); + } + + public static void reset(RavenwoodRule rule) { + android.os.Process.reset$ravenwood(); + android.os.Binder.reset$ravenwood(); + } +} diff --git a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java index 0aac084dd4ce..edb0442e7b29 100644 --- a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java +++ b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java @@ -22,12 +22,30 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY - * QUESTIONS ABOUT IT. + * Test methods marked with this annotation are quietly ignored when running under a Ravenwood test + * environment. The test continues to execute normally under all other non-Ravenwood test + * environments. + * + * This annotation only takes effect when the containing class has a {@code + * RavenwoodRule} configured. Ignoring is accomplished by throwing an {@code org.junit + * .AssumptionViolatedException} which test infrastructure treats as being ignored. + * + * Developers are encouraged to use either the {@code blockedBy} and/or {@code reason} arguments + * to document why a test is being ignored, to aid in future audits of tests that are candidates + * to be enabled. * * @hide */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface IgnoreUnderRavenwood { + /** + * One or more classes that aren't yet supported by Ravenwood, which this test depends on. + */ + Class<?>[] blockedBy() default {}; + + /** + * General free-form description of why this test is being ignored. + */ + String reason() default ""; } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java index bffd0cdc9412..79f9e58aaa1a 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java @@ -16,7 +16,6 @@ package android.platform.test.ravenwood; -import android.os.Process; import android.platform.test.annotations.IgnoreUnderRavenwood; import org.junit.Assume; @@ -35,12 +34,16 @@ import java.util.concurrent.atomic.AtomicInteger; public class RavenwoodRule implements TestRule { private static AtomicInteger sNextPid = new AtomicInteger(100); + private static final int SYSTEM_UID = 1000; + private static final int NOBODY_UID = 9999; + private static final int FIRST_APPLICATION_UID = 10000; + /** * Unless the test author requests differently, run as "nobody", and give each collection of * tests its own unique PID. */ - private int mUid = android.os.Process.NOBODY_UID; - private int mPid = sNextPid.getAndIncrement(); + int mUid = NOBODY_UID; + int mPid = sNextPid.getAndIncrement(); public RavenwoodRule() { } @@ -56,7 +59,7 @@ public class RavenwoodRule implements TestRule { * test. Has no effect under non-Ravenwood environments. */ public Builder setProcessSystem() { - mRule.mUid = android.os.Process.SYSTEM_UID; + mRule.mUid = SYSTEM_UID; return this; } @@ -65,7 +68,7 @@ public class RavenwoodRule implements TestRule { * test. Has no effect under non-Ravenwood environments. */ public Builder setProcessApp() { - mRule.mUid = android.os.Process.FIRST_APPLICATION_UID; + mRule.mUid = FIRST_APPLICATION_UID; return this; } @@ -82,16 +85,6 @@ public class RavenwoodRule implements TestRule { return System.getProperty("java.class.path").contains("ravenwood"); } - private void init() { - android.os.Process.init$ravenwood(mUid, mPid); - android.os.Binder.init$ravenwood(); - } - - private void reset() { - android.os.Process.reset$ravenwood(); - android.os.Binder.reset$ravenwood(); - } - @Override public Statement apply(Statement base, Description description) { return new Statement() { @@ -102,13 +95,13 @@ public class RavenwoodRule implements TestRule { Assume.assumeFalse(isUnderRavenwood); } if (isUnderRavenwood) { - init(); + RavenwoodRuleImpl.init(RavenwoodRule.this); } try { base.evaluate(); } finally { if (isUnderRavenwood) { - reset(); + RavenwoodRuleImpl.reset(RavenwoodRule.this); } } } diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java new file mode 100644 index 000000000000..ecaff8084888 --- /dev/null +++ b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.platform.test.ravenwood; + +public class RavenwoodRuleImpl { + public static void init(RavenwoodRule rule) { + // Must be provided by impl to reference runtime internals + throw new UnsupportedOperationException(); + } + + public static void reset(RavenwoodRule rule) { + // Must be provided by impl to reference runtime internals + throw new UnsupportedOperationException(); + } +} diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/ravenwood-annotation-allowed-classes.txt index 128155cc63df..df44fde2ed72 100644 --- a/ravenwood/ravenwood-annotation-allowed-classes.txt +++ b/ravenwood/ravenwood-annotation-allowed-classes.txt @@ -35,3 +35,6 @@ android.database.MatrixCursor android.database.MatrixCursor$RowBuilder android.database.MergeCursor android.database.Observable + +android.text.TextUtils +android.text.TextUtils$SimpleStringSplitter diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index f73b00c1fcce..041cd75f82e7 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -34,6 +34,8 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCE import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; +import static com.android.window.flags.Flags.removeCaptureDisplay; + import android.accessibilityservice.AccessibilityGestureEvent; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; @@ -1440,42 +1442,86 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); return; } - final long identity = Binder.clearCallingIdentity(); - try { - mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { - final ScreenshotHardwareBuffer screenshotBuffer = LocalServices - .getService(DisplayManagerInternal.class).userScreenshot(displayId); - if (screenshotBuffer != null) { - sendScreenshotSuccess(screenshotBuffer, callback); - } else { - sendScreenshotFailure( - AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, callback); - } - }, null).recycleOnUse()); - } finally { - Binder.restoreCallingIdentity(identity); + if (removeCaptureDisplay()) { + try { + ScreenCapture.ScreenCaptureListener screenCaptureListener = new + ScreenCapture.ScreenCaptureListener( + (screenshotBuffer, result) -> { + if (screenshotBuffer != null && result == 0) { + sendScreenshotSuccess(screenshotBuffer, callback); + } else { + sendScreenshotFailure( + AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, + callback); + } + } + ); + mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener); + } catch (Exception e) { + sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, + callback); + } finally { + Binder.restoreCallingIdentity(identity); + } + } else { + try { + mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { + final ScreenshotHardwareBuffer screenshotBuffer = LocalServices + .getService(DisplayManagerInternal.class).userScreenshot(displayId); + if (screenshotBuffer != null) { + sendScreenshotSuccess(screenshotBuffer, callback); + } else { + sendScreenshotFailure( + AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY, + callback); + } + }, null).recycleOnUse()); + } finally { + Binder.restoreCallingIdentity(identity); + } } } private void sendScreenshotSuccess(ScreenshotHardwareBuffer screenshotBuffer, RemoteCallback callback) { - final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); - final ParcelableColorSpace colorSpace = - new ParcelableColorSpace(screenshotBuffer.getColorSpace()); - - final Bundle payload = new Bundle(); - payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, - AccessibilityService.TAKE_SCREENSHOT_SUCCESS); - payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, - hardwareBuffer); - payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace); - payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP, - SystemClock.uptimeMillis()); - - // Send back the result. - callback.sendResult(payload); - hardwareBuffer.close(); + if (removeCaptureDisplay()) { + mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { + final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); + final ParcelableColorSpace colorSpace = + new ParcelableColorSpace(screenshotBuffer.getColorSpace()); + + final Bundle payload = new Bundle(); + payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, + AccessibilityService.TAKE_SCREENSHOT_SUCCESS); + payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, + hardwareBuffer); + payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace); + payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP, + SystemClock.uptimeMillis()); + + // Send back the result. + callback.sendResult(payload); + hardwareBuffer.close(); + }, null).recycleOnUse()); + } else { + final HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer(); + final ParcelableColorSpace colorSpace = + new ParcelableColorSpace(screenshotBuffer.getColorSpace()); + + final Bundle payload = new Bundle(); + payload.putInt(KEY_ACCESSIBILITY_SCREENSHOT_STATUS, + AccessibilityService.TAKE_SCREENSHOT_SUCCESS); + payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER, + hardwareBuffer); + payload.putParcelable(KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE, colorSpace); + payload.putLong(KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP, + SystemClock.uptimeMillis()); + + // Send back the result. + callback.sendResult(payload); + hardwareBuffer.close(); + } } private void sendScreenshotFailure(@AccessibilityService.ScreenshotErrorCode int errorCode, diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java index 45ca7260bbe7..d31b1efafcc4 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -69,6 +69,7 @@ import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.AccessibilityTraceManager; +import com.android.server.accessibility.Flags; import com.android.server.accessibility.gestures.GestureUtils; /** @@ -261,8 +262,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } mDelegatingState = new DelegatingState(); - mDetectingState = new DetectingState(context); - mViewportDraggingState = new ViewportDraggingState(); + mDetectingState = Flags.enableMagnificationMultipleFingerMultipleTapGesture() + ? new DetectingStateWithMultiFinger(context) + : new DetectingState(context); + mViewportDraggingState = Flags.enableMagnificationMultipleFingerMultipleTapGesture() + ? new ViewportDraggingStateWithMultiFinger() + : new ViewportDraggingState(); mPanningScalingState = new PanningScalingState(context); mSinglePanningState = new SinglePanningState(context); mFullScreenMagnificationVibrationHelper = fullScreenMagnificationVibrationHelper; @@ -634,6 +639,62 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } + final class ViewportDraggingStateWithMultiFinger extends ViewportDraggingState { + // LINT.IfChange(viewport_dragging_state_with_multi_finger) + @Override + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) + throws GestureException { + final int action = event.getActionMasked(); + switch (action) { + case ACTION_POINTER_DOWN: { + clearAndTransitToPanningScalingState(); + } + break; + case ACTION_MOVE: { + if (event.getPointerCount() > 2) { + throw new GestureException("Should have one pointer down."); + } + final float eventX = event.getX(); + final float eventY = event.getY(); + if (mFullScreenMagnificationController.magnificationRegionContains( + mDisplayId, eventX, eventY)) { + mFullScreenMagnificationController.setCenter(mDisplayId, eventX, eventY, + /* animate */ mLastMoveOutsideMagnifiedRegion, + AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID); + mLastMoveOutsideMagnifiedRegion = false; + } else { + mLastMoveOutsideMagnifiedRegion = true; + } + } + break; + + case ACTION_UP: + case ACTION_CANCEL: { + // If mScaleToRecoverAfterDraggingEnd >= 1.0, the dragging state is triggered + // by zoom in temporary, and the magnifier needs to recover to original scale + // after exiting dragging state. + // Otherwise, the magnifier should be disabled. + if (mScaleToRecoverAfterDraggingEnd >= 1.0f) { + zoomToScale(mScaleToRecoverAfterDraggingEnd, event.getX(), + event.getY()); + } else { + zoomOff(); + } + clear(); + mScaleToRecoverAfterDraggingEnd = Float.NaN; + transitionTo(mDetectingState); + } + break; + + case ACTION_DOWN: { + throw new GestureException( + "Unexpected event type: " + MotionEvent.actionToString(action)); + } + } + } + // LINT.ThenChange(:viewport_dragging_state) + } + /** * This class handles motion events when the event dispatcher has * determined that the user is performing a single-finger drag of the @@ -643,17 +704,18 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH * of the finger, and any part of the screen is reachable without lifting the finger. * This makes it the preferable mode for tasks like reading text spanning full screen width. */ - final class ViewportDraggingState implements State { + class ViewportDraggingState implements State { /** * The cached scale for recovering after dragging ends. * If the scale >= 1.0, the magnifier needs to recover to scale. * Otherwise, the magnifier should be disabled. */ - @VisibleForTesting float mScaleToRecoverAfterDraggingEnd = Float.NaN; + @VisibleForTesting protected float mScaleToRecoverAfterDraggingEnd = Float.NaN; - private boolean mLastMoveOutsideMagnifiedRegion; + protected boolean mLastMoveOutsideMagnifiedRegion; + // LINT.IfChange(viewport_dragging_state) @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) throws GestureException { @@ -706,6 +768,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } } + // LINT.ThenChange(:viewport_dragging_state_with_multi_finger) private boolean isAlwaysOnMagnificationEnabled() { return mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled(); @@ -732,7 +795,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH ? mFullScreenMagnificationController.getScale(mDisplayId) : Float.NaN; } - private void clearAndTransitToPanningScalingState() { + protected void clearAndTransitToPanningScalingState() { final float scaleToRecovery = mScaleToRecoverAfterDraggingEnd; clear(); mScaleToRecoverAfterDraggingEnd = scaleToRecovery; @@ -791,36 +854,220 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } + final class DetectingStateWithMultiFinger extends DetectingState { + // A flag set to true when two fingers have touched down. + // Used to indicate what next finger action should be. + private boolean mIsTwoFingerCountReached = false; + // A tap counts when two fingers are down and up once. + private int mCompletedTapCount = 0; + DetectingStateWithMultiFinger(Context context) { + super(context); + } + + // LINT.IfChange(detecting_state_with_multi_finger) + @Override + public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { + cacheDelayedMotionEvent(event, rawEvent, policyFlags); + switch (event.getActionMasked()) { + case MotionEvent.ACTION_DOWN: { + mLastDetectingDownEventTime = event.getDownTime(); + mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE); + + mFirstPointerDownLocation.set(event.getX(), event.getY()); + + if (!mFullScreenMagnificationController.magnificationRegionContains( + mDisplayId, event.getX(), event.getY())) { + + transitionToDelegatingStateAndClear(); + + } else if (isMultiTapTriggered(2 /* taps */)) { + + // 3tap and hold + afterLongTapTimeoutTransitionToDraggingState(event); + + } else if (isTapOutOfDistanceSlop()) { + + transitionToDelegatingStateAndClear(); + + } else if (mDetectSingleFingerTripleTap + || mDetectTwoFingerTripleTap + // If activated, delay an ACTION_DOWN for mMultiTapMaxDelay + // to ensure reachability of + // STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN) + || isActivated()) { + + afterMultiTapTimeoutTransitionToDelegatingState(); + + } else { + + // Delegate pending events without delay + transitionToDelegatingStateAndClear(); + } + } + break; + case ACTION_POINTER_DOWN: { + mIsTwoFingerCountReached = mDetectTwoFingerTripleTap + && event.getPointerCount() == 2; + mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE); + + if (isActivated() && event.getPointerCount() == 2) { + storePointerDownLocation(mSecondPointerDownLocation, event); + mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE, + ViewConfiguration.getTapTimeout()); + } else if (mIsTwoFingerCountReached) { + // Placing two-finger triple-taps behind isActivated to avoid + // blocking panning scaling state + if (isMultiFingerMultiTapTriggered(/* targetTapCount= */ 2, event)) { + // 3tap and hold + afterLongTapTimeoutTransitionToDraggingState(event); + } else { + afterMultiTapTimeoutTransitionToDelegatingState(); + } + } else { + transitionToDelegatingStateAndClear(); + } + } + break; + case ACTION_POINTER_UP: { + // If it is a two-finger gesture, do not transition to the delegating state + // to ensure the reachability of + // the two-finger triple tap (triggerable with ACTION_MOVE and ACTION_UP) + if (!mIsTwoFingerCountReached) { + transitionToDelegatingStateAndClear(); + } + } + break; + case ACTION_MOVE: { + if (isFingerDown() + && distance(mLastDown, /* move */ event) > mSwipeMinDistance) { + // Swipe detected - transition immediately + + // For convenience, viewport dragging takes precedence + // over insta-delegating on 3tap&swipe + // (which is a rare combo to be used aside from magnification) + if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) { + transitionToViewportDraggingStateAndClear(event); + } else if (isActivated() && event.getPointerCount() == 2) { + if (mIsSinglePanningEnabled + && overscrollState(event, mFirstPointerDownLocation) + == OVERSCROLL_VERTICAL_EDGE) { + transitionToDelegatingStateAndClear(); + } + //Primary pointer is swiping, so transit to PanningScalingState + transitToPanningScalingStateAndClear(); + } else if (isMultiFingerMultiTapTriggered(/* targetTapCount= */ 2, event) + && event.getPointerCount() == 2) { + // Placing two-finger triple-taps behind isActivated to avoid + // blocking panning scaling state + transitionToViewportDraggingStateAndClear(event); + } else if (mIsSinglePanningEnabled + && isActivated() + && event.getPointerCount() == 1) { + if (overscrollState(event, mFirstPointerDownLocation) + == OVERSCROLL_VERTICAL_EDGE) { + transitionToDelegatingStateAndClear(); + } + transitToSinglePanningStateAndClear(); + } else { + transitionToDelegatingStateAndClear(); + } + } else if (isActivated() && pointerDownValid(mSecondPointerDownLocation) + && distanceClosestPointerToPoint( + mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) { + //Second pointer is swiping, so transit to PanningScalingState + transitToPanningScalingStateAndClear(); + } + } + break; + case ACTION_UP: { + + mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD); + + if (!mFullScreenMagnificationController.magnificationRegionContains( + mDisplayId, event.getX(), event.getY())) { + transitionToDelegatingStateAndClear(); + + } else if (isMultiTapTriggered(3 /* taps */)) { + onTripleTap(/* up */ event); + + } else if (isMultiFingerMultiTapTriggered(/* targetTapCount= */ 3, event)) { + onTripleTap(event); + + } else if ( + // Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP + isFingerDown() + //TODO long tap should never happen here + && ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay) + || (distance(mLastDown, mLastUp) >= mSwipeMinDistance)) + // If it is a two-finger but not reach 3 tap, do not transition to the + // delegating state to ensure the reachability of the triple tap + && mCompletedTapCount == 0) { + transitionToDelegatingStateAndClear(); + + } + } + break; + } + } + // LINT.ThenChange(:detecting_state) + + @Override + public void clear() { + mCompletedTapCount = 0; + setShortcutTriggered(false); + removePendingDelayedMessages(); + clearDelayedMotionEvents(); + mFirstPointerDownLocation.set(Float.NaN, Float.NaN); + mSecondPointerDownLocation.set(Float.NaN, Float.NaN); + } + + private boolean isMultiFingerMultiTapTriggered(int targetTapCount, MotionEvent event) { + if (event.getActionMasked() == ACTION_UP && mIsTwoFingerCountReached) { + mCompletedTapCount++; + mIsTwoFingerCountReached = false; + } + return mDetectTwoFingerTripleTap && mCompletedTapCount == targetTapCount; + } + + void transitionToDelegatingStateAndClear() { + mCompletedTapCount = 0; + transitionTo(mDelegatingState); + sendDelayedMotionEvents(); + removePendingDelayedMessages(); + mFirstPointerDownLocation.set(Float.NaN, Float.NaN); + mSecondPointerDownLocation.set(Float.NaN, Float.NaN); + } + } + /** * This class handles motion events when the event dispatch has not yet * determined what the user is doing. It watches for various tap events. */ - final class DetectingState implements State, Handler.Callback { + class DetectingState implements State, Handler.Callback { - private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1; - private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2; - private static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3; + protected static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1; + protected static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2; + protected static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3; final int mLongTapMinDelay; final int mSwipeMinDistance; final int mMultiTapMaxDelay; final int mMultiTapMaxDistance; - private MotionEventInfo mDelayedEventQueue; - MotionEvent mLastDown; - private MotionEvent mPreLastDown; - private MotionEvent mLastUp; - private MotionEvent mPreLastUp; - private PointF mSecondPointerDownLocation = new PointF(Float.NaN, Float.NaN); + protected MotionEventInfo mDelayedEventQueue; + protected MotionEvent mLastDown; + protected MotionEvent mPreLastDown; + protected MotionEvent mLastUp; + protected MotionEvent mPreLastUp; - private long mLastDetectingDownEventTime; + protected PointF mFirstPointerDownLocation = new PointF(Float.NaN, Float.NaN); + protected PointF mSecondPointerDownLocation = new PointF(Float.NaN, Float.NaN); + protected long mLastDetectingDownEventTime; @VisibleForTesting boolean mShortcutTriggered; @VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this); - private PointF mFirstPointerDownLocation = new PointF(Float.NaN, Float.NaN); - DetectingState(Context context) { mLongTapMinDelay = ViewConfiguration.getLongPressTimeout(); mMultiTapMaxDelay = ViewConfiguration.getDoubleTapTimeout() @@ -855,6 +1102,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH return true; } + // LINT.IfChange(detecting_state) @Override public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { cacheDelayedMotionEvent(event, rawEvent, policyFlags); @@ -969,23 +1217,24 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH break; } } + // LINT.ThenChange(:detecting_state_with_multi_finger) - private void storePointerDownLocation(PointF pointerDownLocation, MotionEvent event) { + protected void storePointerDownLocation(PointF pointerDownLocation, MotionEvent event) { final int index = event.getActionIndex(); pointerDownLocation.set(event.getX(index), event.getY(index)); } - private boolean pointerDownValid(PointF pointerDownLocation) { + protected boolean pointerDownValid(PointF pointerDownLocation) { return !(Float.isNaN(pointerDownLocation.x) && Float.isNaN( pointerDownLocation.y)); } - private void transitToPanningScalingStateAndClear() { + protected void transitToPanningScalingStateAndClear() { transitionTo(mPanningScalingState); clear(); } - private void transitToSinglePanningStateAndClear() { + protected void transitToSinglePanningStateAndClear() { transitionTo(mSinglePanningState); clear(); } @@ -1016,7 +1265,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH return mLastDown != null; } - private long timeBetween(@Nullable MotionEvent a, @Nullable MotionEvent b) { + protected long timeBetween(@Nullable MotionEvent a, @Nullable MotionEvent b) { if (a == null && b == null) return 0; return abs(timeOf(a) - timeOf(b)); } @@ -1061,13 +1310,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH mSecondPointerDownLocation.set(Float.NaN, Float.NaN); } - private void removePendingDelayedMessages() { + protected void removePendingDelayedMessages() { mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD); mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE); mHandler.removeMessages(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE); } - private void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent, + protected void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) { if (event.getActionMasked() == ACTION_DOWN) { mPreLastDown = mLastDown; @@ -1090,7 +1339,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } - private void sendDelayedMotionEvents() { + protected void sendDelayedMotionEvents() { if (mDelayedEventQueue == null) { return; } @@ -1112,7 +1361,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } while (mDelayedEventQueue != null); } - private void clearDelayedMotionEvents() { + protected void clearDelayedMotionEvents() { while (mDelayedEventQueue != null) { MotionEventInfo info = mDelayedEventQueue; mDelayedEventQueue = info.mNext; @@ -1136,7 +1385,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH * 1. direct three tap gesture * 2. one tap while shortcut triggered (it counts as two taps). */ - private void onTripleTap(MotionEvent up) { + protected void onTripleTap(MotionEvent up) { if (DEBUG_DETECTING) { Slog.i(mLogTag, "onTripleTap(); delayed: " + MotionEventInfo.toString(mDelayedEventQueue)); @@ -1156,7 +1405,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH clear(); } - private boolean isActivated() { + protected boolean isActivated() { return mFullScreenMagnificationController.isActivated(mDisplayId); } @@ -1167,6 +1416,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH // Only log the 3tap and hold event if (!shortcutTriggered) { + // TODO:(b/309534286): Add metrics for two-finger triple-tap and fix + // the log two-finger bug before enabling the flag // Triple tap and hold also belongs to triple tap event final boolean enabled = !isActivated(); mMagnificationLogger.logMagnificationTripleTap(enabled); diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java index 202f68bdeb4a..a570d0989134 100644 --- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java +++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java @@ -20,9 +20,11 @@ import android.annotation.NonNull; import android.companion.virtual.camera.IVirtualCameraCallback; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtual.camera.VirtualCameraStreamConfig; +import android.companion.virtualcamera.Format; import android.companion.virtualcamera.IVirtualCameraService; import android.companion.virtualcamera.SupportedStreamConfiguration; import android.companion.virtualcamera.VirtualCameraConfiguration; +import android.graphics.ImageFormat; import android.os.RemoteException; import android.view.Surface; @@ -85,10 +87,14 @@ public final class VirtualCameraConversionUtil { SupportedStreamConfiguration supportedConfig = new SupportedStreamConfiguration(); supportedConfig.height = stream.getHeight(); supportedConfig.width = stream.getWidth(); - supportedConfig.pixelFormat = stream.getFormat(); + supportedConfig.pixelFormat = convertFormat(stream.getFormat()); return supportedConfig; } + private static int convertFormat(int format) { + return format == ImageFormat.YUV_420_888 ? Format.YUV_420_888 : Format.UNKNOWN; + } + private VirtualCameraConversionUtil() { } } diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java index 0d423d8a0a62..2ba3a1d751d0 100644 --- a/services/core/java/com/android/server/VpnManagerService.java +++ b/services/core/java/com/android/server/VpnManagerService.java @@ -33,7 +33,6 @@ import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.INetd; import android.net.IVpnManager; -import android.net.LinkProperties; import android.net.Network; import android.net.NetworkStack; import android.net.UnderlyingNetworkInfo; @@ -437,16 +436,9 @@ public class VpnManagerService extends IVpnManager.Stub { throw new UnsupportedOperationException("Legacy VPN is deprecated"); } int user = UserHandle.getUserId(mDeps.getCallingUid()); - // Note that if the caller is not system (uid >= Process.FIRST_APPLICATION_UID), - // the code might not work well since getActiveNetwork might return null if the uid is - // blocked by NetworkPolicyManagerService. - final LinkProperties egress = mCm.getLinkProperties(mCm.getActiveNetwork()); - if (egress == null) { - throw new IllegalStateException("Missing active network connection"); - } synchronized (mVpns) { throwIfLockdownEnabled(); - mVpns.get(user).startLegacyVpn(profile, null /* underlying */, egress); + mVpns.get(user).startLegacyVpn(profile); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b2a794865a48..b19b6447dfcd 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6563,7 +6563,7 @@ public class ActivityManagerService extends IActivityManager.Stub | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); final Intent intent = new Intent(); - intent.setData(uri); + intent.setData(ContentProvider.maybeAddUserId(uri, userId)); intent.setFlags(modeFlags); final NeededUriGrants needed = mUgmInternal.checkGrantUriPermissionFromIntent(intent, diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index a95ddf38e659..9d8f979e883c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -4157,7 +4157,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" -D: enable debugging"); pw.println(" --suspend: debugged app suspend threads at startup (only with -D)"); pw.println(" -N: enable native debugging"); - pw.println(" -W: wait for launch to complete"); + pw.println(" -W: wait for launch to complete (initial display)"); pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>"); pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); pw.println(" between samples (use with --start-profiler)"); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index ddccce5963b3..b30334632b55 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1829,7 +1829,7 @@ public class OomAdjuster { // screen on or animating, promote UI state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI); state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP); - } else { + } else if (!app.getWindowProcessController().isShowingUiWhileDozing()) { // screen off, restrict UI scheduling state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); state.setCurrentSchedulingGroup(SCHED_GROUP_RESTRICTED); diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java index 108f53ff4485..0ee7d9cdd3d4 100644 --- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java +++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceImpl.java @@ -305,26 +305,6 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface } @Override - public boolean areUidModesDefault(int uid) { - synchronized (mLock) { - SparseIntArray opModes = mUidModes.get(uid); - return (opModes == null || opModes.size() <= 0); - } - } - - @Override - public boolean arePackageModesDefault(@NonNull String packageName, @UserIdInt int userId) { - synchronized (mLock) { - ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null); - if (packageModes == null) { - return true; - } - SparseIntArray opModes = packageModes.get(packageName); - return (opModes == null || opModes.size() <= 0); - } - } - - @Override public boolean removePackage(String packageName, @UserIdInt int userId) { synchronized (mLock) { ArrayMap<String, SparseIntArray> packageModes = mUserPackageModes.get(userId, null); diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java index 60d17cd388f6..f6e6bc0be8fa 100644 --- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java +++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceInterface.java @@ -124,21 +124,6 @@ public interface AppOpsCheckingServiceInterface { void removeUid(int uid); /** - * Returns true if all uid modes for this uid are - * in default state. - * @param uid user id - */ - boolean areUidModesDefault(int uid); - - /** - * Returns true if all package modes for this package name are - * in default state. - * @param packageName package name. - * @param userId user id associated with the package. - */ - boolean arePackageModesDefault(String packageName, @UserIdInt int userId); - - /** * Stop tracking app-op modes for all uid and packages. */ void clearAllModes(); diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java index 3fee59bd1c2f..ccdf3a5baa7b 100644 --- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java +++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceLoggingDecorator.java @@ -111,19 +111,6 @@ public class AppOpsCheckingServiceLoggingDecorator implements AppOpsCheckingServ } @Override - public boolean areUidModesDefault(int uid) { - Log.i(LOG_TAG, "areUidModesDefault(uid = " + uid + ")"); - return mService.areUidModesDefault(uid); - } - - @Override - public boolean arePackageModesDefault(String packageName, int userId) { - Log.i(LOG_TAG, "arePackageModesDefault(packageName = " + packageName + ", userId = " - + userId + ")"); - return mService.arePackageModesDefault(packageName, userId); - } - - @Override public void clearAllModes() { Log.i(LOG_TAG, "clearAllModes()"); mService.clearAllModes(); diff --git a/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java index c0cc8b176613..c3a02a84a277 100644 --- a/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java +++ b/services/core/java/com/android/server/appop/AppOpsCheckingServiceTracingDecorator.java @@ -168,28 +168,6 @@ public class AppOpsCheckingServiceTracingDecorator implements AppOpsCheckingServ } @Override - public boolean areUidModesDefault(int uid) { - Trace.traceBegin(TRACE_TAG, - "TaggedTracingAppOpsCheckingServiceInterfaceImpl#areUidModesDefault"); - try { - return mService.areUidModesDefault(uid); - } finally { - Trace.traceEnd(TRACE_TAG); - } - } - - @Override - public boolean arePackageModesDefault(String packageName, @UserIdInt int userId) { - Trace.traceBegin(TRACE_TAG, - "TaggedTracingAppOpsCheckingServiceInterfaceImpl#arePackageModesDefault"); - try { - return mService.arePackageModesDefault(packageName, userId); - } finally { - Trace.traceEnd(TRACE_TAG); - } - } - - @Override public void clearAllModes() { Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#clearAllModes"); diff --git a/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java b/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java index de73a5514792..98e6476e9707 100644 --- a/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java +++ b/services/core/java/com/android/server/appop/AppOpsServiceTestingShim.java @@ -149,30 +149,6 @@ public class AppOpsServiceTestingShim implements AppOpsCheckingServiceInterface } @Override - public boolean areUidModesDefault(int uid) { - boolean oldVal = mOldImplementation.areUidModesDefault(uid); - boolean newVal = mNewImplementation.areUidModesDefault(uid); - - if (oldVal != newVal) { - signalImplDifference("areUidModesDefault"); - } - - return newVal; - } - - @Override - public boolean arePackageModesDefault(String packageName, int userId) { - boolean oldVal = mOldImplementation.arePackageModesDefault(packageName, userId); - boolean newVal = mNewImplementation.arePackageModesDefault(packageName, userId); - - if (oldVal != newVal) { - signalImplDifference("arePackageModesDefault"); - } - - return newVal; - } - - @Override public void clearAllModes() { mOldImplementation.clearAllModes(); mNewImplementation.clearAllModes(); diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index a12243b8e4fa..aef224843b2f 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -2549,15 +2549,14 @@ public class Vpn { * secondary thread to perform connection work, returning quickly. * * Should only be called to respond to Binder requests as this enforces caller permission. Use - * {@link #startLegacyVpnPrivileged(VpnProfile, Network, LinkProperties)} to skip the + * {@link #startLegacyVpnPrivileged(VpnProfile)} to skip the * permission check only when the caller is trusted (or the call is initiated by the system). */ - public void startLegacyVpn(VpnProfile profile, @Nullable Network underlying, - LinkProperties egress) { + public void startLegacyVpn(VpnProfile profile) { enforceControlPermission(); final long token = Binder.clearCallingIdentity(); try { - startLegacyVpnPrivileged(profile, underlying, egress); + startLegacyVpnPrivileged(profile); } finally { Binder.restoreCallingIdentity(token); } @@ -2616,13 +2615,13 @@ public class Vpn { } /** - * Like {@link #startLegacyVpn(VpnProfile, Network, LinkProperties)}, but does not - * check permissions under the assumption that the caller is the system. + * Like {@link #startLegacyVpn(VpnProfile)}, but does not check permissions under + * the assumption that the caller is the system. * * Callers are responsible for checking permissions if needed. */ - public void startLegacyVpnPrivileged(VpnProfile profile, - @Nullable Network underlying, @NonNull LinkProperties egress) { + public void startLegacyVpnPrivileged(VpnProfile profileToStart) { + final VpnProfile profile = profileToStart.clone(); UserInfo user = mUserManager.getUserInfo(mUserId); if (user.isRestricted() || mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_VPN, new UserHandle(mUserId))) { @@ -3385,6 +3384,13 @@ public class Vpn { * given network to start a new IKE session. */ private void startOrMigrateIkeSession(@Nullable Network underlyingNetwork) { + synchronized (Vpn.this) { + // Ignore stale runner. + if (mVpnRunner != this) return; + setVpnNetworkPreference(mSessionKey, + createUserAndRestrictedProfilesRanges(mUserId, + mConfig.allowedApplications, mConfig.disallowedApplications)); + } if (underlyingNetwork == null) { // For null underlyingNetwork case, there will not be a NetworkAgent available so // no underlying network update is necessary here. Note that updating @@ -3905,6 +3911,7 @@ public class Vpn { updateState(DetailedState.FAILED, exception.getMessage()); } + clearVpnNetworkPreference(mSessionKey); disconnectVpnRunner(); } @@ -4039,6 +4046,13 @@ public class Vpn { } resetIkeState(); + if (errorCode != VpnManager.ERROR_CODE_NETWORK_LOST + // Clear the VPN network preference when the retry delay is higher than 5s. + // mRetryCount was increased when scheduleRetryNewIkeSession() is called, + // therefore use mRetryCount - 1 here. + && mDeps.getNextRetryDelayMs(mRetryCount - 1) > 5_000L) { + clearVpnNetworkPreference(mSessionKey); + } } /** @@ -4085,13 +4099,17 @@ public class Vpn { mCarrierConfigManager.unregisterCarrierConfigChangeListener( mCarrierConfigChangeListener); mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); - clearVpnNetworkPreference(mSessionKey); mExecutor.shutdown(); } @Override public void exitVpnRunner() { + // mSessionKey won't be changed since the Ikev2VpnRunner is created, so it's ok to use + // it outside the mExecutor. And clearing the VPN network preference here can prevent + // the case that the VPN network preference isn't cleared when Ikev2VpnRunner became + // stale. + clearVpnNetworkPreference(mSessionKey); try { mExecutor.execute(() -> { disconnectVpnRunner(); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java index c01bc2063a59..f992a2399c61 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecNetwork.java @@ -921,6 +921,9 @@ public class HdmiCecNetwork { * port id. */ int portIdToPath(int portId) { + if (portId == Constants.CEC_SWITCH_HOME) { + return getPhysicalAddress(); + } HdmiPortInfo portInfo = getPortInfo(portId); if (portInfo == null) { Slog.e(TAG, "Cannot find the port info: " + portId); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java index a46d7197100f..14daf62a9ed2 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java @@ -56,9 +56,13 @@ public abstract class InputMethodManagerInternal { public abstract void setInteractive(boolean interactive); /** - * Hides the current input method, if visible. + * Hides the input methods for all the users, if visible. + * + * @param reason the reason for hiding the current input method + * @param originatingDisplayId the display ID the request is originated */ - public abstract void hideCurrentInputMethod(@SoftInputShowHideReason int reason); + public abstract void hideAllInputMethods(@SoftInputShowHideReason int reason, + int originatingDisplayId); /** * Returns the list of installed input methods for the specified user. @@ -210,7 +214,8 @@ public abstract class InputMethodManagerInternal { } @Override - public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) { + public void hideAllInputMethods(@SoftInputShowHideReason int reason, + int originatingDisplayId) { } @Override diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 6cc069377bf2..ddb32fe09d6c 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -226,7 +226,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private static final int MSG_SHOW_IM_SUBTYPE_PICKER = 1; - private static final int MSG_HIDE_CURRENT_INPUT_METHOD = 1035; + private static final int MSG_HIDE_ALL_INPUT_METHODS = 1035; private static final int MSG_REMOVE_IME_SURFACE = 1060; private static final int MSG_REMOVE_IME_SURFACE_FROM_WINDOW = 1061; private static final int MSG_UPDATE_IME_WINDOW_STATUS = 1070; @@ -4835,7 +4835,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // --------------------------------------------------------- - case MSG_HIDE_CURRENT_INPUT_METHOD: + case MSG_HIDE_ALL_INPUT_METHODS: synchronized (ImfLock.class) { final @SoftInputShowHideReason int reason = (int) msg.obj; hideCurrentInputLocked(mCurFocusedWindow, null /* statsToken */, 0 /* flags */, @@ -5591,9 +5591,10 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } @Override - public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) { - mHandler.removeMessages(MSG_HIDE_CURRENT_INPUT_METHOD); - mHandler.obtainMessage(MSG_HIDE_CURRENT_INPUT_METHOD, reason).sendToTarget(); + public void hideAllInputMethods(@SoftInputShowHideReason int reason, + int originatingDisplayId) { + mHandler.removeMessages(MSG_HIDE_ALL_INPUT_METHODS); + mHandler.obtainMessage(MSG_HIDE_ALL_INPUT_METHODS, reason).sendToTarget(); } @Override diff --git a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java index f49fa6ecca4a..0185190521a3 100644 --- a/services/core/java/com/android/server/inputmethod/SubtypeUtils.java +++ b/services/core/java/com/android/server/inputmethod/SubtypeUtils.java @@ -86,8 +86,7 @@ final class SubtypeUtils { continue; } } - if (mode == SUBTYPE_MODE_ANY || TextUtils.isEmpty(mode) - || mode.equalsIgnoreCase(subtype.getMode())) { + if (TextUtils.isEmpty(mode) || mode.equalsIgnoreCase(subtype.getMode())) { return true; } } diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 1b7d1ba59b06..9a0b3914122c 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -208,7 +208,7 @@ public class LockdownVpnTracker { // network is the system default. So, if the VPN is up and underlying network // (e.g., wifi) disconnects, CS will inform apps that the VPN's capabilities have // changed to match the new default network (e.g., cell). - mVpn.startLegacyVpnPrivileged(mProfile, network, egressProp); + mVpn.startLegacyVpnPrivileged(mProfile); } catch (IllegalStateException e) { mAcceptedEgressIface = null; Log.e(TAG, "Failed to start VPN", e); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7e5152669837..bae06347d8a2 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -706,7 +706,6 @@ public class NotificationManagerService extends SystemService { private boolean mNotificationEffectsEnabledForAutomotive; private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener; protected NotificationAttentionHelper mAttentionHelper; - private boolean mFlagRefactorAttentionHelper; private int mWarnRemoteViewsSizeBytes; private int mStripRemoteViewsSizeBytes; @@ -1190,7 +1189,7 @@ public class NotificationManagerService extends SystemService { @Override public void onSetDisabled(int status) { synchronized (mNotificationLock) { - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.updateDisableNotificationEffectsLocked(status); } else { mDisableNotificationEffects = @@ -1336,7 +1335,7 @@ public class NotificationManagerService extends SystemService { public void clearEffects() { synchronized (mNotificationLock) { if (DBG) Slog.d(TAG, "clearEffects"); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.clearAttentionEffects(); } else { clearSoundLocked(); @@ -1565,7 +1564,7 @@ public class NotificationManagerService extends SystemService { int changedFlags = data.getFlags() ^ flags; if ((changedFlags & FLAG_SUPPRESS_NOTIFICATION) != 0) { // Suppress notification flag changed, clear any effects - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.clearEffectsLocked(key); } else { clearEffectsLocked(key); @@ -1914,7 +1913,7 @@ public class NotificationManagerService extends SystemService { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if (!mFlagRefactorAttentionHelper) { + if (!Flags.refactorAttentionHelper()) { if (action.equals(Intent.ACTION_SCREEN_ON)) { // Keep track of screen on/off state, but do not turn off the notification light // until user passes through the lock screen or views the notification. @@ -2030,7 +2029,7 @@ public class NotificationManagerService extends SystemService { ContentResolver resolver = getContext().getContentResolver(); resolver.registerContentObserver(NOTIFICATION_BADGING_URI, false, this, UserHandle.USER_ALL); - if (!mFlagRefactorAttentionHelper) { + if (!Flags.refactorAttentionHelper()) { resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this, UserHandle.USER_ALL); } @@ -2060,7 +2059,7 @@ public class NotificationManagerService extends SystemService { public void update(Uri uri) { ContentResolver resolver = getContext().getContentResolver(); - if (!mFlagRefactorAttentionHelper) { + if (!Flags.refactorAttentionHelper()) { if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) { boolean pulseEnabled = Settings.System.getIntForUser(resolver, Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT) @@ -2561,9 +2560,7 @@ public class NotificationManagerService extends SystemService { mToastRateLimiter = toastRateLimiter; - //Cache aconfig flag value - mFlagRefactorAttentionHelper = Flags.refactorAttentionHelper(); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper = new NotificationAttentionHelper(getContext(), lightsManager, mAccessibilityManager, mPackageManagerClient, userManager, usageStats, mNotificationManagerPrivate, mZenModeHelper, flagResolver); @@ -2573,7 +2570,7 @@ public class NotificationManagerService extends SystemService { // If this is called within a test, make sure to unregister the intent receivers by // calling onDestroy() IntentFilter filter = new IntentFilter(); - if (!mFlagRefactorAttentionHelper) { + if (!Flags.refactorAttentionHelper()) { filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); @@ -2901,7 +2898,7 @@ public class NotificationManagerService extends SystemService { } registerNotificationPreferencesPullers(); new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.onSystemReady(); } } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { @@ -6574,7 +6571,7 @@ public class NotificationManagerService extends SystemService { pw.println(" mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate); pw.println(" hideSilentStatusBar=" + mPreferencesHelper.shouldHideSilentStatusIcons()); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.dump(pw, " ", filter); } } @@ -7875,7 +7872,7 @@ public class NotificationManagerService extends SystemService { boolean wasPosted = removeFromNotificationListsLocked(r); cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null, SystemClock.elapsedRealtime()); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.updateLightsLocked(); } else { updateLightsLocked(); @@ -8015,7 +8012,7 @@ public class NotificationManagerService extends SystemService { cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName, mSendDelete, childrenFlagChecker, mReason, mCancellationElapsedTimeMs); - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.updateLightsLocked(); } else { updateLightsLocked(); @@ -8312,7 +8309,7 @@ public class NotificationManagerService extends SystemService { int buzzBeepBlinkLoggingCode = 0; if (!r.isHidden()) { - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { buzzBeepBlinkLoggingCode = mAttentionHelper.buzzBeepBlinkLocked(r, new NotificationAttentionHelper.Signals( mUserProfiles.isCurrentProfile(r.getUserId()), @@ -9299,7 +9296,7 @@ public class NotificationManagerService extends SystemService { || interruptiveChanged; if (interceptBefore && !record.isIntercepted() && record.isNewEnoughForAlerting(System.currentTimeMillis())) { - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.buzzBeepBlinkLocked(record, new NotificationAttentionHelper.Signals( mUserProfiles.isCurrentProfile(record.getUserId()), mListenerHints)); @@ -9679,7 +9676,7 @@ public class NotificationManagerService extends SystemService { }); } - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.clearEffectsLocked(canceledKey); } else { // sound @@ -10043,7 +10040,7 @@ public class NotificationManagerService extends SystemService { cancellationElapsedTimeMs); } } - if (mFlagRefactorAttentionHelper) { + if (Flags.refactorAttentionHelper()) { mAttentionHelper.updateLightsLocked(); } else { updateLightsLocked(); diff --git a/services/core/java/com/android/server/pdb/PersistentDataBlockService.java b/services/core/java/com/android/server/pdb/PersistentDataBlockService.java index a8cba532435d..f985b5b64e21 100644 --- a/services/core/java/com/android/server/pdb/PersistentDataBlockService.java +++ b/services/core/java/com/android/server/pdb/PersistentDataBlockService.java @@ -355,15 +355,7 @@ public class PersistentDataBlockService extends SystemService { private boolean computeAndWriteDigestLocked() { byte[] digest = computeDigestLocked(null); if (digest != null) { - FileChannel channel; - try { - channel = getBlockOutputChannel(); - } catch (IOException e) { - Slog.e(TAG, "partition not available?", e); - return false; - } - - try { + try (FileChannel channel = getBlockOutputChannel()) { ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES); buf.put(digest); buf.flip(); @@ -424,8 +416,7 @@ public class PersistentDataBlockService extends SystemService { @VisibleForTesting void formatPartitionLocked(boolean setOemUnlockEnabled) { - try { - FileChannel channel = getBlockOutputChannel(); + try (FileChannel channel = getBlockOutputChannel()) { // Format the data selectively. // // 1. write header, set length = 0 @@ -471,8 +462,7 @@ public class PersistentDataBlockService extends SystemService { private void doSetOemUnlockEnabledLocked(boolean enabled) { - try { - FileChannel channel = getBlockOutputChannel(); + try (FileChannel channel = getBlockOutputChannel()) { channel.position(getBlockDeviceSize() - 1); @@ -554,14 +544,6 @@ public class PersistentDataBlockService extends SystemService { return (int) -maxBlockSize; } - FileChannel channel; - try { - channel = getBlockOutputChannel(); - } catch (IOException e) { - Slog.e(TAG, "partition not available?", e); - return -1; - } - ByteBuffer headerAndData = ByteBuffer.allocate( data.length + HEADER_SIZE + DIGEST_SIZE_BYTES); headerAndData.put(new byte[DIGEST_SIZE_BYTES]); @@ -574,7 +556,7 @@ public class PersistentDataBlockService extends SystemService { return -1; } - try { + try (FileChannel channel = getBlockOutputChannel()) { channel.write(headerAndData); channel.force(true); } catch (IOException e) { @@ -831,8 +813,7 @@ public class PersistentDataBlockService extends SystemService { if (!mIsWritable) { return; } - try { - FileChannel channel = getBlockOutputChannel(); + try (FileChannel channel = getBlockOutputChannel()) { channel.position(offset); channel.write(dataBuffer); channel.force(true); diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java index 50ed3b1859df..af6a002e66c4 100644 --- a/services/core/java/com/android/server/pm/ApkChecksums.java +++ b/services/core/java/com/android/server/pm/ApkChecksums.java @@ -111,6 +111,11 @@ public class ApkChecksums { private static final Certificate[] EMPTY_CERTIFICATE_ARRAY = {}; /** + * Arbitrary size restriction for the signature, used to sign the checksums. + */ + private static final int MAX_SIGNATURE_SIZE_BYTES = 35 * 1024; + + /** * Check back in 1 second after we detected we needed to wait for the APK to be fully available. */ private static final long PROCESS_REQUIRED_CHECKSUMS_DELAY_MILLIS = 1000; @@ -260,6 +265,10 @@ public class ApkChecksums { */ public static @NonNull Certificate[] verifySignature(Checksum[] checksums, byte[] signature) throws NoSuchAlgorithmException, IOException, SignatureException { + if (signature == null || signature.length > MAX_SIGNATURE_SIZE_BYTES) { + throw new SignatureException("Invalid signature"); + } + final byte[] blob; try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { writeChecksums(os, checksums); diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java index d5dacce3c8ce..eff6157380c0 100644 --- a/services/core/java/com/android/server/pm/PackageArchiver.java +++ b/services/core/java/com/android/server/pm/PackageArchiver.java @@ -22,6 +22,7 @@ import static android.content.pm.ArchivedActivityInfo.bytesFromBitmap; import static android.content.pm.ArchivedActivityInfo.drawableToBitmap; import static android.content.pm.PackageManager.DELETE_ARCHIVE; import static android.content.pm.PackageManager.DELETE_KEEP_DATA; +import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT; import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; @@ -61,6 +62,7 @@ import android.os.Process; import android.os.SELinux; import android.os.UserHandle; import android.text.TextUtils; +import android.util.ExceptionUtils; import android.util.Slog; import com.android.internal.R; @@ -398,7 +400,45 @@ public class PackageArchiver { packageName))); } - mPm.mHandler.post(() -> unarchiveInternal(packageName, userHandle, installerPackage)); + int draftSessionId; + try { + draftSessionId = createDraftSession(packageName, installerPackage, userId); + } catch (RuntimeException e) { + if (e.getCause() instanceof IOException) { + throw ExceptionUtils.wrap((IOException) e.getCause()); + } else { + throw e; + } + } + + mPm.mHandler.post( + () -> unarchiveInternal(packageName, userHandle, installerPackage, draftSessionId)); + } + + private int createDraftSession(String packageName, String installerPackage, int userId) { + PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams( + PackageInstaller.SessionParams.MODE_FULL_INSTALL); + sessionParams.setAppPackageName(packageName); + sessionParams.installFlags = INSTALL_UNARCHIVE_DRAFT; + int installerUid = mPm.snapshotComputer().getPackageUid(installerPackage, 0, userId); + // Handles case of repeated unarchival calls for the same package. + int existingSessionId = mPm.mInstallerService.getExistingDraftSessionId(installerUid, + sessionParams, + userId); + if (existingSessionId != PackageInstaller.SessionInfo.INVALID_ID) { + return existingSessionId; + } + + int sessionId = Binder.withCleanCallingIdentity( + () -> mPm.mInstallerService.createSessionInternal( + sessionParams, + installerPackage, mContext.getAttributionTag(), + installerUid, + userId)); + // TODO(b/297358628) Also cleanup sessions upon device restart. + mPm.mHandler.postDelayed(() -> mPm.mInstallerService.cleanupDraftIfUnclaimed(sessionId), + getUnarchiveForegroundTimeout()); + return sessionId; } /** @@ -461,7 +501,7 @@ public class PackageArchiver { cloudDrawable.getIntrinsicWidth(), cloudDrawable.getIntrinsicHeight()); LayerDrawable layerDrawable = - new LayerDrawable(new Drawable[] {appIconDrawable, cloudDrawable}); + new LayerDrawable(new Drawable[]{appIconDrawable, cloudDrawable}); final int iconSize = mContext.getSystemService( ActivityManager.class).getLauncherLargeIconSize(); Bitmap appIconWithCloudOverlay = drawableToBitmap(layerDrawable, iconSize); @@ -487,10 +527,11 @@ public class PackageArchiver { android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}, conditional = true) private void unarchiveInternal(String packageName, UserHandle userHandle, - String installerPackage) { + String installerPackage, int unarchiveId) { int userId = userHandle.getIdentifier(); Intent unarchiveIntent = new Intent(Intent.ACTION_UNARCHIVE_PACKAGE); unarchiveIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_ID, unarchiveId); unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_PACKAGE_NAME, packageName); unarchiveIntent.putExtra(PackageInstaller.EXTRA_UNARCHIVE_ALL_USERS, userId == UserHandle.USER_ALL); diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 98eee4dc3b1d..af43a8bec832 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -18,7 +18,9 @@ package com.android.server.pm; import static android.app.admin.DevicePolicyResources.Strings.Core.PACKAGE_DELETED_BY_DO; import static android.content.pm.PackageInstaller.LOCATION_DATA_APP; +import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT; import static android.os.Process.INVALID_UID; +import static android.os.Process.SYSTEM_UID; import static com.android.server.pm.PackageManagerService.SHELL_PACKAGE_NAME; @@ -633,17 +635,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements + "to use a data loader"); } + // Draft sessions cannot be created through the public API. + params.installFlags &= ~PackageManager.INSTALL_UNARCHIVE_DRAFT; return createSessionInternal(params, installerPackageName, callingAttributionTag, - userId); + Binder.getCallingUid(), userId); } catch (IOException e) { throw ExceptionUtils.wrap(e); } } - private int createSessionInternal(SessionParams params, String installerPackageName, - String installerAttributionTag, int userId) + int createSessionInternal(SessionParams params, String installerPackageName, + String installerAttributionTag, int callingUid, int userId) throws IOException { - final int callingUid = Binder.getCallingUid(); final Computer snapshot = mPm.snapshotComputer(); snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "createSession"); @@ -692,7 +695,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements // initiatingPackageName installerPackageName = SHELL_PACKAGE_NAME; } else { - if (callingUid != Process.SYSTEM_UID) { + if (callingUid != SYSTEM_UID) { // The supplied installerPackageName must always belong to the calling app. mAppOps.checkPackage(callingUid, installerPackageName); } @@ -707,6 +710,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements params.installFlags &= ~PackageManager.INSTALL_FROM_ADB; params.installFlags &= ~PackageManager.INSTALL_ALL_USERS; + params.installFlags &= ~PackageManager.INSTALL_ARCHIVED; params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; if ((params.installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0 && !mPm.isCallerVerifier(snapshot, callingUid)) { @@ -903,6 +907,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } } + int requestedInstallerPackageUid = INVALID_UID; + if (requestedInstallerPackageName != null) { + requestedInstallerPackageUid = snapshot.getPackageUid(requestedInstallerPackageName, + 0 /* flags */, userId); + } + if (requestedInstallerPackageUid == INVALID_UID) { + // Requested installer package is invalid, reset it + requestedInstallerPackageName = null; + } + final int sessionId; final PackageInstallerSession session; synchronized (mSessions) { @@ -923,8 +937,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements throw new IllegalStateException( "Too many historical sessions for UID " + callingUid); } + final int existingDraftSessionId = + getExistingDraftSessionId(requestedInstallerPackageUid, params, userId); - sessionId = allocateSessionIdLocked(); + sessionId = existingDraftSessionId != SessionInfo.INVALID_ID ? existingDraftSessionId + : allocateSessionIdLocked(); } final long createdMillis = System.currentTimeMillis(); @@ -945,15 +962,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements params.forceQueryableOverride = false; } } - int requestedInstallerPackageUid = INVALID_UID; - if (requestedInstallerPackageName != null) { - requestedInstallerPackageUid = snapshot.getPackageUid(requestedInstallerPackageName, - 0 /* flags */, userId); - } - if (requestedInstallerPackageUid == INVALID_UID) { - // Requested installer package is invalid, reset it - requestedInstallerPackageName = null; - } final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class); if (dpmi != null && dpmi.isUserOrganizationManaged(userId)) { @@ -988,6 +996,68 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements return sessionId; } + int getExistingDraftSessionId(int installerUid, + @NonNull SessionParams sessionParams, int userId) { + synchronized (mSessions) { + return getExistingDraftSessionIdInternal(installerUid, sessionParams, userId); + } + } + + @GuardedBy("mSessions") + private int getExistingDraftSessionIdInternal(int installerUid, + SessionParams sessionParams, int userId) { + String appPackageName = sessionParams.appPackageName; + if (!Flags.archiving() || installerUid == INVALID_UID || appPackageName == null) { + return SessionInfo.INVALID_ID; + } + + PackageStateInternal ps = mPm.snapshotComputer().getPackageStateInternal(appPackageName, + SYSTEM_UID); + if (ps == null || !PackageArchiver.isArchived(ps.getUserStateOrDefault(userId))) { + return SessionInfo.INVALID_ID; + } + + // If unarchiveId is present we match based on it. If unarchiveId is missing we + // choose a draft session too to ensure we don't end up with duplicate sessions + // if the installer doesn't set this field. + if (sessionParams.unarchiveId > 0) { + PackageInstallerSession session = mSessions.get(sessionParams.unarchiveId); + if (session != null + && isValidDraftSession(session, appPackageName, installerUid, userId)) { + return session.sessionId; + } + + return SessionInfo.INVALID_ID; + } + + for (int i = 0; i < mSessions.size(); i++) { + PackageInstallerSession session = mSessions.valueAt(i); + if (session != null + && isValidDraftSession(session, appPackageName, installerUid, userId)) { + return session.sessionId; + } + } + + return SessionInfo.INVALID_ID; + } + + private boolean isValidDraftSession(@NonNull PackageInstallerSession session, + @NonNull String appPackageName, int installerUid, int userId) { + return (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT) != 0 + && appPackageName.equals(session.params.appPackageName) + && session.userId == userId + && installerUid == session.getInstallerUid(); + } + + void cleanupDraftIfUnclaimed(int sessionId) { + synchronized (mSessions) { + PackageInstallerSession session = mPm.mInstallerService.getSession(sessionId); + if (session != null && (session.getInstallFlags() & INSTALL_UNARCHIVE_DRAFT) != 0) { + session.abandon(); + } + } + } + private boolean isStagedInstallerAllowed(String installerName) { return SystemConfig.getInstance().getWhitelistedStagedInstallers().contains(installerName); } @@ -1053,7 +1123,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } private boolean checkOpenSessionAccess(final PackageInstallerSession session) { - if (session == null) { + if (session == null + || (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT) != 0) { return false; } if (isCallingUidOwner(session)) { @@ -1248,10 +1319,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements final PackageInstallerSession session = mSessions.valueAt(i); SessionInfo info = - session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID); + session.generateInfoForCaller(false /*withIcon*/, SYSTEM_UID); if (Objects.equals(info.getInstallerPackageName(), installerPackageName) && session.userId == userId && !session.hasParentSessionId() - && isCallingUidOwner(session)) { + && isCallingUidOwner(session) + && (session.getInstallFlags() & PackageManager.INSTALL_UNARCHIVE_DRAFT) + == 0) { result.add(info); } } @@ -1602,7 +1675,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements PackageInstallerSession session = null; try { var sessionId = createSessionInternal(params, installerPackageName, - null /*installerAttributionTag*/, userId); + null /*installerAttributionTag*/, Binder.getCallingUid(), userId); session = openSessionInternal(sessionId); session.addFile(LOCATION_DATA_APP, "base", 0 /*lengthBytes*/, metadata.toByteArray(), null /*signature*/); @@ -2017,7 +2090,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements // we don't scrub the data here as this is sent only to the installer several // privileged system packages sendSessionUpdatedBroadcast( - session.generateInfoForCaller(false/*icon*/, Process.SYSTEM_UID), + session.generateInfoForCaller(false/*icon*/, SYSTEM_UID), session.userId); } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 52fdfd12d9f2..d38c0a0920b1 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1612,7 +1612,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { try { Certificate[] ignored = ApkChecksums.verifySignature(checksums, signature); } catch (IOException | NoSuchAlgorithmException | SignatureException e) { - throw new IllegalArgumentException("Can't verify signature", e); + throw new IllegalArgumentException("Can't verify signature: " + e.getMessage(), e); } } @@ -2248,31 +2248,39 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { == PackageManager.PERMISSION_GRANTED; } + private boolean isInstallationAllowed(PackageStateInternal psi) { + if (psi == null || psi.getPkg() == null) { + return true; + } + if (psi.getPkg().isUpdatableSystem()) { + return true; + } + if (mOriginalInstallerUid == Process.ROOT_UID) { + Slog.w(TAG, "Overriding updatableSystem because the installer is root: " + + psi.getPackageName()); + return true; + } + return false; + } + /** * Check if this package can be installed archived. */ - private static boolean isArchivedInstallationAllowed(String packageName) { - final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); - final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(packageName); - if (existingPkgSetting == null) { + private static boolean isArchivedInstallationAllowed(PackageStateInternal psi) { + if (psi == null) { return true; } - return false; } /** * Checks if the package can be installed on IncFs. */ - private static boolean isIncrementalInstallationAllowed(String packageName) { - final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); - final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(packageName); - if (existingPkgSetting == null || existingPkgSetting.getPkg() == null) { + private static boolean isIncrementalInstallationAllowed(PackageStateInternal psi) { + if (psi == null || psi.getPkg() == null) { return true; } - - return !existingPkgSetting.isSystem() - && !existingPkgSetting.isUpdatedSystemApp(); + return !psi.isSystem() && !psi.isUpdatedSystemApp(); } /** @@ -3371,6 +3379,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Split " + apk.getSplitName() + " was defined multiple times"); } + if (!apk.isUpdatableSystem()) { + if (mOriginalInstallerUid == Process.ROOT_UID) { + Slog.w(TAG, "Overriding updatableSystem because the installer is root for: " + + apk.getPackageName()); + } else { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, + "Non updatable system package can't be installed or updated"); + } + } + // Use first package to define unknown values if (mPackageName == null) { mPackageName = apk.getPackageName(); @@ -3445,8 +3463,17 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); + final PackageStateInternal existingPkgSetting = pmi.getPackageStateInternal(mPackageName); + + if (!isInstallationAllowed(existingPkgSetting)) { + throw new PackageManagerException( + PackageManager.INSTALL_FAILED_SESSION_INVALID, + "Installation of this package is not allowed."); + } + if (isArchivedInstallation()) { - if (!isArchivedInstallationAllowed(mPackageName)) { + if (!isArchivedInstallationAllowed(existingPkgSetting)) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_SESSION_INVALID, "Archived installation of this package is not allowed."); @@ -3462,7 +3489,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } if (isIncrementalInstallation()) { - if (!isIncrementalInstallationAllowed(mPackageName)) { + if (!isIncrementalInstallationAllowed(existingPkgSetting)) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_SESSION_INVALID, "Incremental installation of this package is not allowed."); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7d3d85d33dcb..ec3823f365b6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3105,7 +3105,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService } private void enforceCanSetPackagesSuspendedAsUser(@NonNull Computer snapshot, - String callingPackage, int callingUid, int userId, String callingMethod) { + boolean quarantined, String callingPackage, int callingUid, int userId, + String callingMethod) { if (callingUid == Process.ROOT_UID // Need to compare app-id to allow system dialogs access on secondary users || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { @@ -3120,8 +3121,20 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, - callingMethod); + if (quarantined) { + final boolean hasQuarantineAppsPerm = mContext.checkCallingOrSelfPermission( + android.Manifest.permission.QUARANTINE_APPS) == PERMISSION_GRANTED; + // TODO: b/305256093 - In order to facilitate testing, temporarily allowing apps + // with SUSPEND_APPS permission to quarantine apps. Remove this once the testing + // is done and this is no longer needed. + if (!hasQuarantineAppsPerm) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, + callingMethod); + } + } else { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS, + callingMethod); + } final int packageUid = snapshot.getPackageUid(callingPackage, 0, userId); final boolean allowedPackageUid = packageUid == callingUid; @@ -6136,9 +6149,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo, int flags, String callingPackage, int userId) { final int callingUid = Binder.getCallingUid(); - final Computer snapshot = snapshotComputer(); - enforceCanSetPackagesSuspendedAsUser(snapshot, callingPackage, callingUid, userId, - "setPackagesSuspendedAsUser"); boolean quarantined = false; if (Flags.quarantinedEnabled()) { if ((flags & PackageManager.FLAG_SUSPEND_QUARANTINED) != 0) { @@ -6149,6 +6159,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService quarantined = callingPackage.equals(wellbeingPkg); } } + final Computer snapshot = snapshotComputer(); + enforceCanSetPackagesSuspendedAsUser(snapshot, quarantined, callingPackage, callingUid, + userId, "setPackagesSuspendedAsUser"); return mSuspendPackageHelper.setPackagesSuspended(snapshot, packageNames, suspended, appExtras, launcherExtras, dialogInfo, callingPackage, userId, callingUid, quarantined); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 7c969ef11666..fd70cb13117f 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4970,6 +4970,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile pw.print(prefix); pw.print(" privateFlags="); printFlags(pw, privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println(); } + if (!pkg.isUpdatableSystem()) { + pw.print(prefix); pw.print(" updatableSystem=false"); + pw.println(); + } if (pkg.hasPreserveLegacyExternalStorage()) { pw.print(prefix); pw.print(" hasPreserveLegacyExternalStorage=true"); pw.println(); diff --git a/services/core/java/com/android/server/pm/UserJourneyLogger.java b/services/core/java/com/android/server/pm/UserJourneyLogger.java index 651578dc5deb..f120763a9e1a 100644 --- a/services/core/java/com/android/server/pm/UserJourneyLogger.java +++ b/services/core/java/com/android/server/pm/UserJourneyLogger.java @@ -23,6 +23,7 @@ import static android.os.UserManager.USER_TYPE_FULL_SECONDARY; import static android.os.UserManager.USER_TYPE_FULL_SYSTEM; import static android.os.UserManager.USER_TYPE_PROFILE_CLONE; import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED; +import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE; import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS; import static com.android.internal.util.FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__UNKNOWN; @@ -245,6 +246,9 @@ public class UserJourneyLogger { .USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__SYSTEM_HEADLESS; case USER_TYPE_PROFILE_CLONE: return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_CLONE; + case USER_TYPE_PROFILE_PRIVATE: + return FrameworkStatsLog + .USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_PRIVATE; default: return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__TYPE_UNKNOWN; } diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java index 370d239ad329..c8ac6982071b 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java @@ -397,7 +397,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, // an APK targeting <R that doesn't contain an <application> tag. That code would be skipped // and never assign this, so initialize this to true for those cases. private long mBooleans = Booleans.ENABLED; - private long mBooleans2; + private long mBooleans2 = Booleans2.UPDATABLE_SYSTEM; @NonNull private Set<String> mKnownActivityEmbeddingCerts = emptySet(); // Derived fields @@ -3451,6 +3451,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, } @Override + public boolean isUpdatableSystem() { + return getBoolean2(Booleans2.UPDATABLE_SYSTEM); + } + + @Override public boolean isFactoryTest() { return getBoolean(Booleans.FACTORY_TEST); } @@ -3522,6 +3527,11 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, } @Override + public PackageImpl setUpdatableSystem(boolean value) { + return setBoolean2(Booleans2.UPDATABLE_SYSTEM, value); + } + + @Override public PackageImpl setFactoryTest(boolean value) { setBoolean(Booleans.FACTORY_TEST, value); return this; @@ -3732,10 +3742,12 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @LongDef({ STUB, APEX, + UPDATABLE_SYSTEM, }) public @interface Flags {} private static final long STUB = 1L; private static final long APEX = 1L << 1; + private static final long UPDATABLE_SYSTEM = 1L << 2; } } diff --git a/services/core/java/com/android/server/pm/parsing/pkg/ParsedPackage.java b/services/core/java/com/android/server/pm/parsing/pkg/ParsedPackage.java index aeaff6dd1458..85f8f7609c2a 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/ParsedPackage.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/ParsedPackage.java @@ -73,6 +73,8 @@ public interface ParsedPackage extends AndroidPackage { ParsedPackage setApex(boolean isApex); + ParsedPackage setUpdatableSystem(boolean value); + ParsedPackage markNotActivitiesAsNotExportedIfSingleUser(); ParsedPackage setOdm(boolean odm); diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java index 883b0666f979..8bd2d94667f9 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java @@ -70,6 +70,7 @@ import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.admin.DevicePolicyManagerInternal; +import android.companion.virtual.VirtualDeviceManager; import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.content.Context; @@ -5327,7 +5328,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt IOnPermissionsChangeListener callback = mPermissionListeners .getBroadcastItem(i); try { - callback.onPermissionsChanged(uid); + callback.onPermissionsChanged(uid, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT); } catch (RemoteException e) { Log.e(TAG, "Permission listener is dead", e); } diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java index 4d4efac4cbe8..99819c82c5df 100644 --- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java +++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java @@ -1393,6 +1393,13 @@ public interface AndroidPackage { /** @hide */ boolean isApex(); + + /** + * @see R.styleable#AndroidManifestApplication_updatableSystem + * @hide + */ + boolean isUpdatableSystem(); + /** * @see ApplicationInfo#enabled * @see R.styleable#AndroidManifestApplication_enabled diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java index 408a531eaf1d..099c67654250 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java @@ -345,6 +345,8 @@ public interface ParsingPackage { ParsingPackage setStaticSharedLibraryVersion(long staticSharedLibraryVersion); + ParsingPackage setUpdatableSystem(boolean value); + ParsingPackage setLargeScreensSupported(int supportsLargeScreens); ParsingPackage setNormalScreensSupported(int supportsNormalScreens); diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index 417e3ae6e7df..e4594c58f40f 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -1002,12 +1002,16 @@ public class ParsingPackageUtils { return sharedUserResult; } + final boolean updatableSystem = parser.getAttributeBooleanValue(null /*namespace*/, + "updatableSystem", true); + pkg.setInstallLocation(anInteger(PARSE_DEFAULT_INSTALL_LOCATION, R.styleable.AndroidManifest_installLocation, sa)) .setTargetSandboxVersion(anInteger(PARSE_DEFAULT_TARGET_SANDBOX, R.styleable.AndroidManifest_targetSandboxVersion, sa)) /* Set the global "on SD card" flag */ - .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0); + .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0) + .setUpdatableSystem(updatableSystem); boolean foundApp = false; final int depth = parser.getDepth(); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 72c10cc9a5e8..1cf82bde633d 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1073,7 +1073,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - private void powerPress(long eventTime, int count) { + private void powerPress(long eventTime, int count, int displayId) { // SideFPS still needs to know about suppressed power buttons, in case it needs to block // an auth attempt. if (count == 1) { @@ -1126,8 +1126,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { break; case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: { if (mDismissImeOnBackKeyPressed) { - InputMethodManagerInternal.get().hideCurrentInputMethod( - SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME); + // TODO(b/308479256): Check if hiding "all" IMEs is OK or not. + InputMethodManagerInternal.get().hideAllInputMethods( + SoftInputShowHideReason.HIDE_POWER_BUTTON_GO_HOME, displayId); } else { shortPressPowerGoHome(); } @@ -2662,11 +2663,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - void onPress(long downTime) { + void onPress(long downTime, int displayId) { if (mShouldEarlyShortPressOnPower) { return; } - powerPress(downTime, 1 /*count*/); + powerPress(downTime, 1 /*count*/, displayId); } @Override @@ -2696,14 +2697,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - void onMultiPress(long downTime, int count) { - powerPress(downTime, count); + void onMultiPress(long downTime, int count, int displayId) { + powerPress(downTime, count, displayId); } @Override - void onKeyUp(long eventTime, int count) { + void onKeyUp(long eventTime, int count, int displayId) { if (mShouldEarlyShortPressOnPower && count == 1) { - powerPress(eventTime, 1 /*pressCount*/); + powerPress(eventTime, 1 /*pressCount*/, displayId); } } } @@ -2727,7 +2728,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - void onPress(long downTime) { + void onPress(long downTime, int unusedDisplayId) { mBackKeyHandled |= backKeyPress(); } @@ -2756,7 +2757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - void onPress(long downTime) { + void onPress(long downTime, int unusedDisplayId) { if (mShouldEarlyShortPressOnStemPrimary) { return; } @@ -2769,12 +2770,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - void onMultiPress(long downTime, int count) { + void onMultiPress(long downTime, int count, int unusedDisplayId) { stemPrimaryPress(count); } @Override - void onKeyUp(long eventTime, int count) { + void onKeyUp(long eventTime, int count, int unusedDisplayId) { if (count == 1) { // Save info about the most recent task on the first press of the stem key. This // may be used later to switch to the most recent app using double press gesture. diff --git a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java index 047555ae491c..a060f504b809 100644 --- a/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java +++ b/services/core/java/com/android/server/policy/SingleKeyGestureDetector.java @@ -66,10 +66,12 @@ public final class SingleKeyGestureDetector { * SingleKeyRule rule = * new SingleKeyRule(KEYCODE_POWER, KEY_LONGPRESS|KEY_VERYLONGPRESS) { * int getMaxMultiPressCount() { // maximum multi press count. } - * void onPress(long downTime) { // short press behavior. } + * void onPress(long downTime, int displayId) { // short press behavior. } * void onLongPress(long eventTime) { // long press behavior. } * void onVeryLongPress(long eventTime) { // very long press behavior. } - * void onMultiPress(long downTime, int count) { // multi press behavior. } + * void onMultiPress(long downTime, int count, int displayId) { + * // multi press behavior. + * } * }; * </pre> */ @@ -114,11 +116,11 @@ public final class SingleKeyGestureDetector { /** * Called when short press has been detected. */ - abstract void onPress(long downTime); + abstract void onPress(long downTime, int displayId); /** * Callback when multi press (>= 2) has been detected. */ - void onMultiPress(long downTime, int count) {} + void onMultiPress(long downTime, int count, int displayId) {} /** * Returns the timeout in milliseconds for a long press. * @@ -148,10 +150,11 @@ public final class SingleKeyGestureDetector { /** * Callback executed upon each key up event that hasn't been processed by long press. * - * @param eventTime the timestamp of this event. - * @param pressCount the number of presses detected leading up to this key up event. + * @param eventTime the timestamp of this event + * @param pressCount the number of presses detected leading up to this key up event + * @param displayId the display ID of the event */ - void onKeyUp(long eventTime, int pressCount) {} + void onKeyUp(long eventTime, int pressCount, int displayId) {} @Override public String toString() { @@ -179,6 +182,10 @@ public final class SingleKeyGestureDetector { } } + private record MessageObject(SingleKeyRule activeRule, int keyCode, int pressCount, + int displayId) { + } + static SingleKeyGestureDetector get(Context context, Looper looper) { SingleKeyGestureDetector detector = new SingleKeyGestureDetector(looper); sDefaultLongPressTimeout = context.getResources().getInteger( @@ -228,8 +235,9 @@ public final class SingleKeyGestureDetector { mHandledByLongPress = true; mHandler.removeMessages(MSG_KEY_LONG_PRESS); mHandler.removeMessages(MSG_KEY_VERY_LONG_PRESS); - final Message msg = mHandler.obtainMessage(MSG_KEY_LONG_PRESS, keyCode, 0, - mActiveRule); + MessageObject object = new MessageObject(mActiveRule, keyCode, /* pressCount= */ 1, + event.getDisplayId()); + final Message msg = mHandler.obtainMessage(MSG_KEY_LONG_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessage(msg); } @@ -275,15 +283,17 @@ public final class SingleKeyGestureDetector { if (mKeyPressCounter == 1) { if (mActiveRule.supportLongPress()) { - final Message msg = mHandler.obtainMessage(MSG_KEY_LONG_PRESS, keyCode, 0, - mActiveRule); + MessageObject object = new MessageObject(mActiveRule, keyCode, mKeyPressCounter, + event.getDisplayId()); + final Message msg = mHandler.obtainMessage(MSG_KEY_LONG_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, mActiveRule.getLongPressTimeoutMs()); } if (mActiveRule.supportVeryLongPress()) { - final Message msg = mHandler.obtainMessage(MSG_KEY_VERY_LONG_PRESS, keyCode, 0, - mActiveRule); + MessageObject object = new MessageObject(mActiveRule, keyCode, mKeyPressCounter, + event.getDisplayId()); + final Message msg = mHandler.obtainMessage(MSG_KEY_VERY_LONG_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, mActiveRule.getVeryLongPressTimeoutMs()); } @@ -299,8 +309,9 @@ public final class SingleKeyGestureDetector { Log.i(TAG, "Trigger multi press " + mActiveRule.toString() + " for it" + " reached the max count " + mKeyPressCounter); } - final Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, keyCode, - mKeyPressCounter, mActiveRule); + MessageObject object = new MessageObject(mActiveRule, keyCode, mKeyPressCounter, + event.getDisplayId()); + final Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessage(msg); } @@ -339,9 +350,9 @@ public final class SingleKeyGestureDetector { if (event.getKeyCode() == mActiveRule.mKeyCode) { // key-up action should always be triggered if not processed by long press. - Message msgKeyUp = - mHandler.obtainMessage( - MSG_KEY_UP, mActiveRule.mKeyCode, mKeyPressCounter, mActiveRule); + MessageObject object = new MessageObject(mActiveRule, mActiveRule.mKeyCode, + mKeyPressCounter, event.getDisplayId()); + Message msgKeyUp = mHandler.obtainMessage(MSG_KEY_UP, object); msgKeyUp.setAsynchronous(true); mHandler.sendMessage(msgKeyUp); @@ -350,8 +361,9 @@ public final class SingleKeyGestureDetector { if (DEBUG) { Log.i(TAG, "press key " + KeyEvent.keyCodeToString(event.getKeyCode())); } - Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode, - 1, mActiveRule); + object = new MessageObject(mActiveRule, mActiveRule.mKeyCode, + /* pressCount= */ 1, event.getDisplayId()); + Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessage(msg); mActiveRule = null; @@ -360,8 +372,9 @@ public final class SingleKeyGestureDetector { // This could be a multi-press. Wait a little bit longer to confirm. if (mKeyPressCounter < mActiveRule.getMaxMultiPressCount()) { - Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode, - mKeyPressCounter, mActiveRule); + object = new MessageObject(mActiveRule, mActiveRule.mKeyCode, + mKeyPressCounter, event.getDisplayId()); + Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, object); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, MULTI_PRESS_TIMEOUT); } @@ -423,20 +436,23 @@ public final class SingleKeyGestureDetector { @Override public void handleMessage(Message msg) { - final SingleKeyRule rule = (SingleKeyRule) msg.obj; + final MessageObject object = (MessageObject) msg.obj; + final SingleKeyRule rule = object.activeRule; if (rule == null) { Log.wtf(TAG, "No active rule."); return; } - final int keyCode = msg.arg1; - final int pressCount = msg.arg2; + final int keyCode = object.keyCode; + final int pressCount = object.pressCount; + final int displayId = object.displayId; switch(msg.what) { case MSG_KEY_UP: if (DEBUG) { - Log.i(TAG, "Detect key up " + KeyEvent.keyCodeToString(keyCode)); + Log.i(TAG, "Detect key up " + KeyEvent.keyCodeToString(keyCode) + + " on display " + displayId); } - rule.onKeyUp(mLastDownTime, pressCount); + rule.onKeyUp(mLastDownTime, pressCount, displayId); break; case MSG_KEY_LONG_PRESS: if (DEBUG) { @@ -454,12 +470,12 @@ public final class SingleKeyGestureDetector { case MSG_KEY_DELAYED_PRESS: if (DEBUG) { Log.i(TAG, "Detect press " + KeyEvent.keyCodeToString(keyCode) - + ", count " + pressCount); + + " on display " + displayId + ", count " + pressCount); } if (pressCount == 1) { - rule.onPress(mLastDownTime); + rule.onPress(mLastDownTime, displayId); } else { - rule.onMultiPress(mLastDownTime, pressCount); + rule.onMultiPress(mLastDownTime, pressCount, displayId); } break; } 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 851a3f7bdaba..83d7d72059b4 100644 --- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java +++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java @@ -188,10 +188,12 @@ public class BatteryUsageStatsProvider { } batteryUsageStatsBuilder.getOrCreateUidBatteryConsumerBuilder(uid) - .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, + .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_BACKGROUND, getProcessBackgroundTimeMs(uid, realtimeUs)) - .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, - getProcessForegroundTimeMs(uid, realtimeUs)); + .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND, + getProcessForegroundTimeMs(uid, realtimeUs)) + .setTimeInProcessStateMs(UidBatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, + getProcessForegroundServiceTimeMs(uid, realtimeUs)); } final int[] powerComponents = query.getPowerComponents(); @@ -295,10 +297,14 @@ public class BatteryUsageStatsProvider { } private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, long realtimeUs) { - return (uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, + return uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, + realtimeUs, BatteryStats.STATS_SINCE_CHARGED) + / 1000; + } + + private long getProcessForegroundServiceTimeMs(BatteryStats.Uid uid, long realtimeUs) { + return uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, realtimeUs, BatteryStats.STATS_SINCE_CHARGED) - + uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, - realtimeUs, BatteryStats.STATS_SINCE_CHARGED)) / 1000; } 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 c1da58943062..17499bb77239 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -1421,6 +1421,7 @@ public class StatsPullAtomService extends SystemService { final NetworkStats nonTaggedStats = NetworkStatsUtils.fromPublicNetworkStats(queryNonTaggedStats); + queryNonTaggedStats.close(); if (!includeTags) return nonTaggedStats; final android.app.usage.NetworkStats queryTaggedStats = @@ -1429,6 +1430,7 @@ public class StatsPullAtomService extends SystemService { currentTimeInMillis); final NetworkStats taggedStats = NetworkStatsUtils.fromPublicNetworkStats(queryTaggedStats); + queryTaggedStats.close(); return nonTaggedStats.add(taggedStats); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 3fd832376d2b..7c51e7b84132 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -1836,12 +1836,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } @Override - public void hideCurrentInputMethodForBubbles() { + public void hideCurrentInputMethodForBubbles(int displayId) { enforceStatusBarService(); final long token = Binder.clearCallingIdentity(); try { - InputMethodManagerInternal.get().hideCurrentInputMethod( - SoftInputShowHideReason.HIDE_BUBBLES); + // TODO(b/308479256): Check if hiding "all" IMEs is OK or not. + InputMethodManagerInternal.get().hideAllInputMethods( + SoftInputShowHideReason.HIDE_BUBBLES, displayId); } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index 7b399c837d32..faccca8981c8 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -70,7 +70,6 @@ import android.app.IRequestFinishCallback; import android.app.PictureInPictureParams; import android.app.PictureInPictureUiState; import android.app.compat.CompatChanges; -import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.EnterPipRequestedItem; import android.app.servertransaction.PipStateTransactionItem; import android.compat.annotation.ChangeId; @@ -1018,7 +1017,7 @@ class ActivityClientController extends IActivityClientController.Stub { } try { - mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), + mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), EnterPipRequestedItem.obtain(r.token)); return true; } catch (Exception e) { @@ -1038,9 +1037,8 @@ class ActivityClientController extends IActivityClientController.Stub { } try { - final ClientTransaction transaction = ClientTransaction.obtain(r.app.getThread()); - transaction.addCallback(PipStateTransactionItem.obtain(r.token, pipState)); - mService.getLifecycleManager().scheduleTransaction(transaction); + mService.getLifecycleManager().scheduleTransactionItem(r.app.getThread(), + PipStateTransactionItem.obtain(r.token, pipState)); } catch (Exception e) { Slog.w(TAG, "Failed to send pip state transaction item: " + r.intent.getComponent(), e); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 24d99387d63c..5ecbc2b95118 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -277,7 +277,6 @@ import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityRelaunchItem; import android.app.servertransaction.ActivityResultItem; -import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.DestroyActivityItem; import android.app.servertransaction.MoveToDisplayItem; @@ -1449,7 +1448,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A + "display, activityRecord=%s, displayId=%d, config=%s", this, displayId, config); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), MoveToDisplayItem.obtain(token, displayId, config)); } catch (RemoteException e) { // If process died, whatever. @@ -1466,7 +1465,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending new config to %s, " + "config: %s", this, config); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), ActivityConfigurationChangeItem.obtain(token, config)); } catch (RemoteException e) { // If process died, whatever. @@ -1487,7 +1486,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b", this, onTop); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), TopResumedActivityChangeItem.obtain(token, onTop)); } catch (RemoteException e) { // If process died, whatever. @@ -1556,9 +1555,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return false; } - // Transition change for the activity moving into a TaskFragment of different bounds. - return newParent.isOrganizedTaskFragment() - && !newParent.getBounds().equals(oldParent.getBounds()); + final boolean isInPip2 = ActivityTaskManagerService.isPip2ExperimentEnabled() + && inPinnedWindowingMode(); + if (!newParent.isOrganizedTaskFragment() && !isInPip2) { + // Parent TaskFragment isn't associated with a TF organizer and we are not in PiP2, + // so do not allow for initializeChangeTransition() on parent changes + return false; + } + // Transition change for the activity moving into TaskFragment of different bounds. + return !newParent.getBounds().equals(oldParent.getBounds()); } @Override @@ -2744,7 +2749,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } try { mTransferringSplashScreenState = TRANSFER_SPLASH_SCREEN_ATTACH_TO_CLIENT; - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), TransferSplashScreenViewStateItem.obtain(token, parcelable, windowAnimationLeash)); scheduleTransferSplashScreenTimeout(); @@ -3908,7 +3913,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A try { if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + this); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), DestroyActivityItem.obtain(token, finishing, configChangeFlags)); } catch (Exception e) { // We can just ignore exceptions here... if the process has crashed, our death @@ -4819,7 +4824,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A try { final ArrayList<ResultInfo> list = new ArrayList<>(); list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), ActivityResultItem.obtain(token, list)); return; } catch (Exception e) { @@ -4830,22 +4835,23 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Schedule sending results now for Media Projection setup. if (forceSendForMediaProjection && attachedToProcess() && isState(STARTED, PAUSING, PAUSED, STOPPING, STOPPED)) { - final ClientTransaction transaction = ClientTransaction.obtain(app.getThread()); // Build result to be returned immediately. - transaction.addCallback(ActivityResultItem.obtain( - token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data)))); + final ActivityResultItem activityResultItem = ActivityResultItem.obtain( + token, List.of(new ResultInfo(resultWho, requestCode, resultCode, data))); // When the activity result is delivered, the activity will transition to RESUMED. // Since the activity is only resumed so the result can be immediately delivered, // return it to its original lifecycle state. - ActivityLifecycleItem lifecycleItem = getLifecycleItemForCurrentStateForResult(); - if (lifecycleItem != null) { - transaction.setLifecycleStateRequest(lifecycleItem); - } else { - Slog.w(TAG, "Unable to get the lifecycle item for state " + mState - + " so couldn't immediately send result"); - } + final ActivityLifecycleItem lifecycleItem = getLifecycleItemForCurrentStateForResult(); try { - mAtmService.getLifecycleManager().scheduleTransaction(transaction); + if (lifecycleItem != null) { + mAtmService.getLifecycleManager().scheduleTransactionAndLifecycleItems( + app.getThread(), activityResultItem, lifecycleItem); + } else { + Slog.w(TAG, "Unable to get the lifecycle item for state " + mState + + " so couldn't immediately send result"); + mAtmService.getLifecycleManager().scheduleTransactionItem( + app.getThread(), activityResultItem); + } } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending result to " + this, e); } @@ -4925,7 +4931,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Making sure the client state is RESUMED after transaction completed and doing // so only if activity is currently RESUMED. Otherwise, client may have extra // life-cycle calls to RESUMED (and PAUSED later). - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), NewIntentItem.obtain(token, ar, mState == RESUMED)); unsent = false; } catch (RemoteException e) { @@ -6150,7 +6156,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A EventLogTags.writeWmPauseActivity(mUserId, System.identityHashCode(this), shortComponentName, "userLeaving=false", "make-active"); try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), PauseActivityItem.obtain(token, finishing, false /* userLeaving */, configChangeFlags, false /* dontReport */, mAutoEnteringPip)); } catch (Exception e) { @@ -6163,7 +6169,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A setState(STARTED, "makeActiveIfNeeded"); try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), StartActivityItem.obtain(token, takeOptions())); } catch (Exception e) { Slog.w(TAG, "Exception thrown sending start: " + intent.getComponent(), e); @@ -6461,7 +6467,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } EventLogTags.writeWmStopActivity( mUserId, System.identityHashCode(this), shortComponentName); - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), StopActivityItem.obtain(token, configChangeFlags)); mAtmService.mH.postDelayed(mStopTimeoutRunnable, STOP_TIMEOUT); @@ -9901,10 +9907,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else { lifecycleItem = PauseActivityItem.obtain(token); } - final ClientTransaction transaction = ClientTransaction.obtain(app.getThread()); - transaction.addCallback(callbackItem); - transaction.setLifecycleStateRequest(lifecycleItem); - mAtmService.getLifecycleManager().scheduleTransaction(transaction); + mAtmService.getLifecycleManager().scheduleTransactionAndLifecycleItems( + app.getThread(), callbackItem, lifecycleItem); startRelaunching(); // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only // request resume if this activity is currently resumed, which implies we aren't @@ -9996,7 +10000,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The process will be killed until the activity reports stopped with saved state (see // {@link ActivityTaskManagerService.activityStopped}). try { - mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(app.getThread(), StopActivityItem.obtain(token, 0 /* configChanges */)); } catch (RemoteException e) { Slog.w(TAG, "Exception thrown during restart " + this, e); diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 3c56a4e5eb04..a9f11e488881 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -125,6 +125,7 @@ import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_R import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT; import static com.android.server.wm.WindowManagerService.MY_PID; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; +import static com.android.sdksandbox.flags.Flags.sandboxActivitySdkBasedContext; import android.Manifest; import android.annotation.IntDef; @@ -165,6 +166,7 @@ import android.app.assist.ActivityId; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.compat.CompatChanges; +import android.app.sdksandbox.sandboxactivity.SdkSandboxActivityAuthority; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; import android.content.ComponentName; @@ -414,6 +416,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { boolean mHasCompanionDeviceSetupFeature; /** The process of the top most activity. */ volatile WindowProcessController mTopApp; + /** The process showing UI while the device is dozing. */ + volatile WindowProcessController mVisibleDozeUiProcess; /** * This is the process holding the activity the user last visited that is in a different process * from the one they are currently in. @@ -1258,6 +1262,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { true /*validateIncomingUser*/); } + static boolean isSdkSandboxActivity(Context context, Intent intent) { + return intent != null + && (sandboxActivitySdkBasedContext() + ? SdkSandboxActivityAuthority.isSdkSandboxActivity(context, intent) + : intent.isSandboxActivity(context)); + } + private int startActivityAsUser(IApplicationThread caller, String callingPackage, @Nullable String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, @@ -1268,7 +1279,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { assertPackageMatchesCallingUid(callingPackage); enforceNotIsolatedCaller("startActivityAsUser"); - if (intent != null && intent.isSandboxActivity(mContext)) { + if (isSdkSandboxActivity(mContext, intent)) { SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager( SdkSandboxManagerLocal.class); sdkSandboxManagerLocal.enforceAllowedToHostSandboxedActivity( diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index e196d463db79..b125dbd8a132 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -98,7 +98,6 @@ import android.app.ResultInfo; import android.app.TaskInfo; import android.app.WaitResult; import android.app.servertransaction.ActivityLifecycleItem; -import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.LaunchActivityItem; import android.app.servertransaction.PauseActivityItem; import android.app.servertransaction.ResumeActivityItem; @@ -928,14 +927,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } // Create activity launch transaction. - final ClientTransaction clientTransaction = ClientTransaction.obtain( - proc.getThread()); - final boolean isTransitionForward = r.isTransitionForward(); final IBinder fragmentToken = r.getTaskFragment().getFragmentToken(); - final int deviceId = getDeviceIdForDisplayId(r.getDisplayId()); - clientTransaction.addCallback(LaunchActivityItem.obtain(r.token, + final LaunchActivityItem launchActivityItem = LaunchActivityItem.obtain(r.token, r.intent, System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global // and override configs. @@ -945,7 +940,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), results, newIntents, r.takeOptions(), isTransitionForward, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, - r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken)); + r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken); // Set desired final state. final ActivityLifecycleItem lifecycleItem; @@ -955,10 +950,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } else { lifecycleItem = PauseActivityItem.obtain(r.token); } - clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. - mService.getLifecycleManager().scheduleTransaction(clientTransaction); + mService.getLifecycleManager().scheduleTransactionAndLifecycleItems( + proc.getThread(), launchActivityItem, lifecycleItem); if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) { // If the seq is increased, there should be something changed (e.g. registered @@ -1089,7 +1084,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Remove the process record so it won't be considered as alive. mService.mProcessNames.remove(wpc.mName, wpc.mUid); mService.mProcessMap.remove(wpc.getPid()); - } else if (r.intent.isSandboxActivity(mService.mContext)) { + } else if (ActivityTaskManagerService.isSdkSandboxActivity(mService.mContext, r.intent)) { Slog.e(TAG, "Abort sandbox activity launching as no sandbox process to host it."); r.finishIfPossible("No sandbox process for the activity", false /* oomAdj */); r.launchFailed = true; diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java index c2b5f88d0b4f..a3e1c8c90d32 100644 --- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java +++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java @@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY; import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel; +import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator; import static com.android.window.flags.Flags.balShowToasts; import static com.android.window.flags.Flags.balShowToastsBlocked; import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS; @@ -42,9 +43,14 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppOpsManager; import android.app.BackgroundStartPrivileges; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledAfter; +import android.compat.annotation.Overridable; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.provider.DeviceConfig; @@ -79,6 +85,12 @@ public class BackgroundActivityStartController { private static final long ASM_GRACEPERIOD_TIMEOUT_MS = TIMEOUT_MS; private static final int ASM_GRACEPERIOD_MAX_REPEATS = 5; private static final int NO_PROCESS_UID = -1; + /** If enabled the creator will not allow BAL on its behalf by default. */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) + @Overridable + private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR = + 296478951; public static final ActivityOptions ACTIVITY_OPTIONS_SYSTEM_DEFINED = ActivityOptions.makeBasic() .setPendingIntentBackgroundActivityStartMode( @@ -264,12 +276,9 @@ public class BackgroundActivityStartController { ? BackgroundStartPrivileges.NONE : BackgroundStartPrivileges.ALLOW_BAL; } else { - // for PendingIntents we restrict creator BAL based on target_sdk - mBalAllowedByPiCreator = - checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode() - == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED - ? BackgroundStartPrivileges.NONE - : BackgroundStartPrivileges.ALLOW_BAL; + // for PendingIntents we restrict BAL based on target_sdk + mBalAllowedByPiCreator = getBackgroundStartPrivilegesAllowedByCreator( + callingUid, callingPackage, checkedOptions); } mBalAllowedByPiSender = PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller( @@ -303,6 +312,45 @@ public class BackgroundActivityStartController { } } + private BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCreator( + int callingUid, String callingPackage, ActivityOptions checkedOptions) { + switch (checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()) { + case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED: + return BackgroundStartPrivileges.ALLOW_BAL; + case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED: + return BackgroundStartPrivileges.NONE; + case ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED: + // no explicit choice by the app - let us decide what to do + Slog.i(TAG, "balRequireOptInByPendingIntentCreator = " + + balRequireOptInByPendingIntentCreator()); + if (!balRequireOptInByPendingIntentCreator()) { + // if feature is disabled allow + return BackgroundStartPrivileges.ALLOW_BAL; + } + if (callingPackage != null) { + // determine based on the calling/creating package + boolean changeEnabled = CompatChanges.isChangeEnabled( + DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR, + callingPackage, + UserHandle.getUserHandleForUid(callingUid)); + Slog.i(TAG, "changeEnabled = " + changeEnabled); + return changeEnabled ? BackgroundStartPrivileges.NONE + : BackgroundStartPrivileges.ALLOW_BAL; + } + // determine based on the calling/creating uid if we cannot determine the + // actual package name (e.g. shared uid) + boolean changeEnabled = CompatChanges.isChangeEnabled( + DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_CREATOR, + callingUid); + Slog.i(TAG, "changeEnabled = " + changeEnabled); + return changeEnabled ? BackgroundStartPrivileges.NONE + : BackgroundStartPrivileges.ALLOW_BAL; + default: + throw new IllegalStateException("unsupported BackgroundActivityStartMode: " + + checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode()); + } + } + private String getDebugPackageName(String packageName, int uid) { if (packageName != null) { return packageName; // use actual package @@ -322,7 +370,7 @@ public class BackgroundActivityStartController { } private boolean isPendingIntent() { - return mOriginatingPendingIntent != null; + return mOriginatingPendingIntent != null && hasRealCaller(); } private String dump(BalVerdict resultIfPiCreatorAllowsBal) { @@ -341,18 +389,23 @@ public class BackgroundActivityStartController { .append(getDebugPackageName(mCallingPackage, mCallingUid)); sb.append("; callingUid: ").append(mCallingUid); sb.append("; callingPid: ").append(mCallingPid); - sb.append("; isPendingIntent: ").append(isPendingIntent()); sb.append("; appSwitchState: ").append(mAppSwitchState); sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow); sb.append("; callingUidProcState: ").append(DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState)); sb.append("; isCallingUidPersistentSystemProcess: ") .append(mIsCallingUidPersistentSystemProcess); + sb.append("; forcedBalByPiSender: ").append(mForcedBalByPiSender); + sb.append("; intent: ").append(mIntent); + sb.append("; callerApp: ").append(mCallerApp); + if (mCallerApp != null) { + sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask()); + } sb.append("; balAllowedByPiCreator: ").append(mBalAllowedByPiCreator); + sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal); sb.append("; hasRealCaller: ").append(hasRealCaller()); sb.append("; isPendingIntent: ").append(isPendingIntent()); if (hasRealCaller()) { - sb.append("; balAllowedByPiSender: ").append(mBalAllowedByPiSender); sb.append("; realCallingPackage: ") .append(getDebugPackageName(mRealCallingPackage, mRealCallingUid)); sb.append("; realCallingUid: ").append(mRealCallingUid); @@ -364,24 +417,14 @@ public class BackgroundActivityStartController { sb.append("; isRealCallingUidPersistentSystemProcess: ") .append(mIsRealCallingUidPersistentSystemProcess); sb.append("; originatingPendingIntent: ").append(mOriginatingPendingIntent); - } - sb.append("; mForcedBalByPiSender: ").append(mForcedBalByPiSender); - sb.append("; intent: ").append(mIntent); - sb.append("; callerApp: ").append(mCallerApp); - if (hasRealCaller()) { sb.append("; realCallerApp: ").append(mRealCallerApp); - } - if (mCallerApp != null) { - sb.append("; inVisibleTask: ").append(mCallerApp.hasActivityInVisibleTask()); - } - if (hasRealCaller()) { if (mRealCallerApp != null) { sb.append("; realInVisibleTask: ") .append(mRealCallerApp.hasActivityInVisibleTask()); } + sb.append("; balAllowedByPiSender: ").append(mBalAllowedByPiSender); sb.append("; resultIfPiSenderAllowsBal: ").append(resultIfPiSenderAllowsBal); } - sb.append("; resultIfPiCreatorAllowsBal: ").append(resultIfPiCreatorAllowsBal); sb.append("]"); return sb.toString(); } @@ -416,10 +459,9 @@ public class BackgroundActivityStartController { public String toString() { StringBuilder builder = new StringBuilder(); - builder.append(". BAL Code: "); builder.append(balCodeToString(mCode)); if (DEBUG_ACTIVITY_STARTS) { - builder.append(" "); + builder.append(" ("); if (mBackground) { builder.append("Background "); } @@ -433,6 +475,7 @@ public class BackgroundActivityStartController { builder.append(" "); builder.append(mProcessInfo); } + builder.append(")"); } return builder.toString(); } @@ -551,29 +594,40 @@ public class BackgroundActivityStartController { && checkedOptions.getPendingIntentBackgroundActivityStartMode() == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) { // Both caller and real caller allow with system defined behavior + if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) { + Slog.wtf(TAG, + "With Android 15 BAL hardening this activity start may be blocked" + + " if the PI creator upgrades target_sdk to 35+" + + " AND the PI sender upgrades target_sdk to 34+! " + + state.dump(resultForCaller, resultForRealCaller)); + showBalRiskToast("BAL would be blocked", state); + // return the realCaller result for backwards compatibility + return statsLog(resultForRealCaller, state); + } Slog.wtf(TAG, - "With Android 15 BAL hardening this activity start may be blocked" - + " if the PI creator upgrades target_sdk to 35+" - + " AND the PI sender upgrades target_sdk to 34+! " - + " (missing opt in by PI creator)! " + "Without Android 15 BAL hardening this activity start would be allowed" + + " (missing opt in by PI creator or sender)! " + state.dump(resultForCaller, resultForRealCaller)); - showBalRiskToast("BAL would be blocked", state); - // return the realCaller result for backwards compatibility - return statsLog(resultForRealCaller, state); - } - if (resultForCaller.allows() + // fall through to abort + } else if (resultForCaller.allows() && checkedOptions.getPendingIntentCreatorBackgroundActivityStartMode() == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) { // Allowed before V by creator + if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) { + Slog.wtf(TAG, + "With Android 15 BAL hardening this activity start may be blocked" + + " if the PI creator upgrades target_sdk to 35+! " + + " (missing opt in by PI creator)! " + + state.dump(resultForCaller, resultForRealCaller)); + showBalRiskToast("BAL would be blocked", state); + return statsLog(resultForCaller, state); + } Slog.wtf(TAG, - "With Android 15 BAL hardening this activity start may be blocked" - + " if the PI creator upgrades target_sdk to 35+! " + "Without Android 15 BAL hardening this activity start would be allowed" + " (missing opt in by PI creator)! " + state.dump(resultForCaller, resultForRealCaller)); - showBalRiskToast("BAL would be blocked", state); - return statsLog(resultForCaller, state); - } - if (resultForRealCaller.allows() + // fall through to abort + } else if (resultForRealCaller.allows() && checkedOptions.getPendingIntentBackgroundActivityStartMode() == ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) { // Allowed before U by sender @@ -589,7 +643,7 @@ public class BackgroundActivityStartController { Slog.wtf(TAG, "Without Android 14 BAL hardening this activity start would be allowed" + " (missing opt in by PI sender)! " + state.dump(resultForCaller, resultForRealCaller)); - // fall through + // fall through to abort } // anything that has fallen through would currently be aborted Slog.w(TAG, "Background activity launch blocked! " diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java index ef31837f810b..28f656e624fb 100644 --- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java +++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java @@ -40,35 +40,51 @@ class ClientLifecycleManager { * @throws RemoteException * * @see ClientTransaction + * @deprecated use {@link #scheduleTransactionItem(IApplicationThread, ClientTransactionItem)}. */ + @Deprecated void scheduleTransaction(@NonNull ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); - transaction.schedule(); - if (!(client instanceof Binder)) { - // If client is not an instance of Binder - it's a remote call and at this point it is - // safe to recycle the object. All objects used for local calls will be recycled after - // the transaction is executed on client in ActivityThread. - transaction.recycle(); + try { + transaction.schedule(); + } finally { + if (!(client instanceof Binder)) { + // If client is not an instance of Binder - it's a remote call and at this point it + // is safe to recycle the object. All objects used for local calls will be recycled + // after the transaction is executed on client in ActivityThread. + transaction.recycle(); + } } } /** * Schedules a single transaction item, either a callback or a lifecycle request, delivery to * client application. - * @param client Target client. - * @param transactionItem A transaction item to deliver a message. * @throws RemoteException - * * @see ClientTransactionItem */ - void scheduleTransaction(@NonNull IApplicationThread client, + void scheduleTransactionItem(@NonNull IApplicationThread client, @NonNull ClientTransactionItem transactionItem) throws RemoteException { final ClientTransaction clientTransaction = ClientTransaction.obtain(client); - if (transactionItem instanceof ActivityLifecycleItem) { + if (transactionItem.isActivityLifecycleItem()) { clientTransaction.setLifecycleStateRequest((ActivityLifecycleItem) transactionItem); } else { clientTransaction.addCallback(transactionItem); } scheduleTransaction(clientTransaction); } + + /** + * Schedules a single transaction item with a lifecycle request, delivery to client application. + * @throws RemoteException + * @see ClientTransactionItem + */ + void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client, + @NonNull ClientTransactionItem transactionItem, + @NonNull ActivityLifecycleItem lifecycleItem) throws RemoteException { + final ClientTransaction clientTransaction = ClientTransaction.obtain(client); + clientTransaction.addCallback(transactionItem); + clientTransaction.setLifecycleStateRequest(lifecycleItem); + scheduleTransaction(clientTransaction); + } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 49248107a004..243c3f26ad61 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1004,6 +1004,24 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mTmpApplySurfaceChangesTransactionState.obscured; final RootWindowContainer root = mWmService.mRoot; + if (w.mHasSurface) { + // Take care of the window being ready to display. + final boolean committed = w.mWinAnimator.commitFinishDrawingLocked(); + if (isDefaultDisplay && committed) { + if (w.hasWallpaper()) { + ProtoLog.v(WM_DEBUG_WALLPAPER, + "First draw done in potential wallpaper target %s", w); + mWallpaperMayChange = true; + pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; + if (DEBUG_LAYOUT_REPEATS) { + surfacePlacer.debugLayoutRepeats( + "wallpaper and commitFinishDrawingLocked true", + pendingLayoutChanges); + } + } + } + } + // Update effect. w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured; @@ -1090,30 +1108,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp w.handleWindowMovedIfNeeded(); - final WindowStateAnimator winAnimator = w.mWinAnimator; - //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); w.resetContentChanged(); - // Moved from updateWindowsAndWallpaperLocked(). - if (w.mHasSurface) { - // Take care of the window being ready to display. - final boolean committed = winAnimator.commitFinishDrawingLocked(); - if (isDefaultDisplay && committed) { - if (w.hasWallpaper()) { - ProtoLog.v(WM_DEBUG_WALLPAPER, - "First draw done in potential wallpaper target %s", w); - mWallpaperMayChange = true; - pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; - if (DEBUG_LAYOUT_REPEATS) { - surfacePlacer.debugLayoutRepeats( - "wallpaper and commitFinishDrawingLocked true", - pendingLayoutChanges); - } - } - } - } - final ActivityRecord activity = w.mActivityRecord; if (activity != null && activity.isVisibleRequested()) { activity.updateLetterboxSurface(w); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index b34f912e1c78..708ee7f59726 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -99,6 +99,7 @@ import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UserHandle; import android.util.ArraySet; import android.util.PrintWriterPrinter; @@ -781,6 +782,12 @@ public class DisplayPolicy { if (!mDisplayContent.isDefaultDisplay) { return; } + if (awake) { + mService.mAtmService.mVisibleDozeUiProcess = null; + } else if (mScreenOnFully && mNotificationShade != null) { + // Screen is still on, so it may be showing an always-on UI. + mService.mAtmService.mVisibleDozeUiProcess = mNotificationShade.getProcess(); + } mService.mAtmService.mKeyguardController.updateDeferTransitionForAod( mAwake /* waiting */); } @@ -826,12 +833,24 @@ public class DisplayPolicy { } public void screenTurnedOn(ScreenOnListener screenOnListener) { + WindowProcessController visibleDozeUiProcess = null; synchronized (mLock) { mScreenOnEarly = true; mScreenOnFully = false; mKeyguardDrawComplete = false; mWindowManagerDrawComplete = false; mScreenOnListener = screenOnListener; + if (!mAwake && mNotificationShade != null) { + // The screen is turned on without awake state. It is usually triggered by an + // adding notification, so make the UI process have a higher priority. + visibleDozeUiProcess = mNotificationShade.getProcess(); + mService.mAtmService.mVisibleDozeUiProcess = visibleDozeUiProcess; + } + } + // The method calls AM directly, so invoke it outside the lock. + if (visibleDozeUiProcess != null) { + Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurnedOnWhileDozing"); + mService.mAtmService.setProcessAnimatingWhileDozing(visibleDozeUiProcess); } } @@ -842,6 +861,7 @@ public class DisplayPolicy { mKeyguardDrawComplete = false; mWindowManagerDrawComplete = false; mScreenOnListener = null; + mService.mAtmService.mVisibleDozeUiProcess = null; } } diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java index 534cdc2015e3..e808decc354d 100644 --- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java @@ -38,7 +38,6 @@ import static com.android.server.wm.DisplayRotationReversionController.REVERSION import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; -import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.RefreshCallbackItem; import android.app.servertransaction.ResumeActivityItem; import android.content.pm.ActivityInfo.ScreenOrientation; @@ -226,13 +225,12 @@ final class DisplayRotationCompatPolicy { ProtoLog.v(WM_DEBUG_STATES, "Refreshing activity for camera compatibility treatment, " + "activityRecord=%s", activity); - final ClientTransaction transaction = ClientTransaction.obtain( - activity.app.getThread()); - transaction.addCallback(RefreshCallbackItem.obtain(activity.token, - cycleThroughStop ? ON_STOP : ON_PAUSE)); - transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(activity.token, - /* isForward */ false, /* shouldSendCompatFakeFocus */ false)); - activity.mAtmService.getLifecycleManager().scheduleTransaction(transaction); + final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain( + activity.token, cycleThroughStop ? ON_STOP : ON_PAUSE); + final ResumeActivityItem resumeActivityItem = ResumeActivityItem.obtain( + activity.token, /* isForward */ false, /* shouldSendCompatFakeFocus */ false); + activity.mAtmService.getLifecycleManager().scheduleTransactionAndLifecycleItems( + activity.app.getThread(), refreshCallbackItem, resumeActivityItem); mHandler.postDelayed( () -> onActivityRefreshed(activity), REFRESH_CALLBACK_TIMEOUT_MS); diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java index 1670b36e4786..b7eab085f5e3 100644 --- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java +++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java @@ -30,7 +30,6 @@ import android.os.RemoteException; import android.util.ArrayMap; import android.util.Slog; import android.util.proto.ProtoOutputStream; -import android.view.IWindow; import android.view.InputApplicationHandle; import android.view.InputChannel; @@ -100,10 +99,10 @@ class EmbeddedWindowController { } } - void remove(IWindow client) { + void remove(IBinder client) { for (int i = mWindows.size() - 1; i >= 0; i--) { EmbeddedWindow ew = mWindows.valueAt(i); - if (ew.mClient == client.asBinder()) { + if (ew.mClient == client) { mWindows.removeAt(i).onRemoved(); mWindowsByInputTransferToken.remove(ew.getInputTransferToken()); mWindowsByWindowToken.remove(ew.getWindowToken()); diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 997b6084f6e2..14912d041127 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -439,8 +439,10 @@ final class InputMonitor { final InputMethodManagerInternal inputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class); if (inputMethodManagerInternal != null) { - inputMethodManagerInternal.hideCurrentInputMethod( - SoftInputShowHideReason.HIDE_RECENTS_ANIMATION); + // TODO(b/308479256): Check if hiding "all" IMEs is OK or not. + inputMethodManagerInternal.hideAllInputMethods( + SoftInputShowHideReason.HIDE_RECENTS_ANIMATION, + mDisplayContent.getDisplayId()); } // Ensure removing the IME snapshot when the app no longer to show on the // task snapshot (also taking the new task snaphot to update the overview). diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index bbb85636f1ee..5c84cb07e891 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -32,6 +32,7 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATI import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.utils.CoordinateTransforms.computeRotationMatrix; +import static com.android.window.flags.Flags.removeCaptureDisplay; import android.animation.ArgbEvaluator; import android.content.Context; @@ -170,7 +171,7 @@ class ScreenRotationAnimation { try { final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer; - if (isSizeChanged) { + if (isSizeChanged && !removeCaptureDisplay()) { final DisplayAddress address = displayInfo.address; if (!(address instanceof DisplayAddress.Physical)) { Slog.e(TAG, "Display does not have a physical address: " + displayId); @@ -196,6 +197,19 @@ class ScreenRotationAnimation { .setHintForSeamlessTransition(true) .build(); screenshotBuffer = ScreenCapture.captureDisplay(captureArgs); + } else if (isSizeChanged) { + // Temporarily not skip screenshot for the rounded corner overlays and screenshot + // the whole display to include the rounded corner overlays. + setSkipScreenshotForRoundedCornerOverlays(false, t); + ScreenCapture.LayerCaptureArgs captureArgs = + new ScreenCapture.LayerCaptureArgs.Builder( + displayContent.getSurfaceControl()) + .setCaptureSecureLayers(true) + .setAllowProtected(true) + .setSourceCrop(new Rect(0, 0, width, height)) + .setHintForSeamlessTransition(true) + .build(); + screenshotBuffer = ScreenCapture.captureLayers(captureArgs); } else { ScreenCapture.LayerCaptureArgs captureArgs = new ScreenCapture.LayerCaptureArgs.Builder( diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 18d64d74613f..56f9aa4c6361 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -253,8 +253,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void remove(IWindow window) { - mService.removeWindow(this, window); + public void remove(IBinder clientToken) { + mService.removeClientToken(this, clientToken); } @Override diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index c9703dbe6311..33f61fe9d3e8 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -3513,7 +3513,8 @@ class Task extends TaskFragment { } appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton = top != null && !appCompatTaskInfo.topActivityInSizeCompat - && top.mLetterboxUiController.shouldEnableUserAspectRatioSettings(); + && top.mLetterboxUiController.shouldEnableUserAspectRatioSettings() + && !info.isTopActivityTransparent; appCompatTaskInfo.topActivityBoundsLetterboxed = top != null && top.areBoundsLetterboxed(); } @@ -4624,7 +4625,12 @@ class Task extends TaskFragment { if (topActivity != null) { mTaskSupervisor.mNoAnimActivities.add(topActivity); } - super.setWindowingMode(windowingMode); + + final boolean isPip2ExperimentEnabled = + ActivityTaskManagerService.isPip2ExperimentEnabled(); + if (!isPip2ExperimentEnabled) { + super.setWindowingMode(windowingMode); + } if (currentMode == WINDOWING_MODE_PINNED && topActivity != null) { // Try reparent pinned activity back to its original task after @@ -4633,32 +4639,37 @@ class Task extends TaskFragment { // PiP, we set final windowing mode on the ActivityRecord first and then on its // Task when the exit PiP transition finishes. Meanwhile, the exit transition is // always performed on its original task, reparent immediately in ActivityRecord - // breaks it. - if (topActivity.getLastParentBeforePip() != null) { - // Do not reparent if the pinned task is in removal, indicated by the - // force hidden flag. - if (!isForceHidden()) { - final Task lastParentBeforePip = topActivity.getLastParentBeforePip(); - if (lastParentBeforePip.isAttached()) { - topActivity.reparent(lastParentBeforePip, - lastParentBeforePip.getChildCount() /* top */, - "movePinnedActivityToOriginalTask"); - final DisplayContent dc = topActivity.getDisplayContent(); - if (dc != null && dc.isFixedRotationLaunchingApp(topActivity)) { - // Expanding pip into new rotation, so create a rotation leash - // until the display is rotated. - topActivity.getOrCreateFixedRotationLeash( - topActivity.getPendingTransaction()); - } - lastParentBeforePip.moveToFront("movePinnedActivityToOriginalTask"); - } + // breaks it. Do not reparent if the pinned task is in removal, indicated by the + // force hidden flag. + if (topActivity.getLastParentBeforePip() != null && !isForceHidden() + && topActivity.getLastParentBeforePip().isAttached()) { + // We need to collect the pip activity to allow for screenshots + // to be taken as a part of reparenting. + mTransitionController.collect(topActivity); + + final Task lastParentBeforePip = topActivity.getLastParentBeforePip(); + topActivity.reparent(lastParentBeforePip, + lastParentBeforePip.getChildCount() /* top */, + "movePinnedActivityToOriginalTask"); + final DisplayContent dc = topActivity.getDisplayContent(); + if (dc != null && dc.isFixedRotationLaunchingApp(topActivity)) { + // Expanding pip into new rotation, so create a rotation leash + // until the display is rotated. + topActivity.getOrCreateFixedRotationLeash( + topActivity.getSyncTransaction()); } + lastParentBeforePip.moveToFront("movePinnedActivityToOriginalTask"); + } + if (isPip2ExperimentEnabled) { + super.setWindowingMode(windowingMode); } // Resume app-switches-allowed flag when exiting from pinned mode since // it does not follow the ActivityStarter path. if (topActivity.shouldBeVisible()) { mAtmService.resumeAppSwitches(); } + } else if (isPip2ExperimentEnabled) { + super.setWindowingMode(windowingMode); } if (creating) { diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 197edc30aa8e..8bc461f05387 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -1793,7 +1793,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev), prev.shortComponentName, "userLeaving=" + userLeaving, reason); - mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), + mAtmService.getLifecycleManager().scheduleTransactionItem(prev.app.getThread(), PauseActivityItem.obtain(prev.token, prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately, autoEnteringPip)); } catch (Exception e) { diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index f1481760a5e7..17ab00d64924 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -394,7 +394,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { boolean taskAppearedSent = t.mTaskAppearedSent; if (taskAppearedSent) { if (t.getSurfaceControl() != null) { - t.migrateToNewSurfaceControl(t.getPendingTransaction()); + t.migrateToNewSurfaceControl(t.getSyncTransaction()); } t.mTaskAppearedSent = false; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 2b77ffffece0..e28262dfbe2f 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -2988,12 +2988,23 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< /** Whether we can start change transition with this window and current display status. */ boolean canStartChangeTransition() { - return !mWmService.mDisableTransitionAnimation && mDisplayContent != null - && getSurfaceControl() != null && !mDisplayContent.inTransition() - && isVisible() && isVisibleRequested() && okToAnimate() - // Pip animation will be handled by PipTaskOrganizer. - && !inPinnedWindowingMode() && getParent() != null - && !getParent().inPinnedWindowingMode(); + if (mWmService.mDisableTransitionAnimation || !okToAnimate()) return false; + + // Change transition only make sense as we go from "visible" to "visible". + if (mDisplayContent == null || getSurfaceControl() == null + || !isVisible() || !isVisibleRequested()) { + return false; + } + + // Make sure display isn't a part of the transition already - needed for legacy transitions. + if (mDisplayContent.inTransition()) return false; + + if (!ActivityTaskManagerService.isPip2ExperimentEnabled()) { + // Screenshots are turned off when PiP is undergoing changes. + return !inPinnedWindowingMode() && getParent() != null + && !getParent().inPinnedWindowingMode(); + } + return true; } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 92bd00e0a175..ae171a0d8030 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -46,6 +46,7 @@ import android.view.SurfaceControlViewHost; import android.view.WindowInfo; import android.view.WindowManager.DisplayImePolicy; import android.view.inputmethod.ImeTracker; +import android.window.ScreenCapture; import com.android.internal.policy.KeyInterceptionInfo; import com.android.server.input.InputManagerService; @@ -979,6 +980,14 @@ public abstract class WindowManagerInternal { public abstract SurfaceControl getA11yOverlayLayer(int displayId); /** + * Captures the entire display specified by the displayId using the args provided. If the args + * are null or if the sourceCrop is invalid or null, the entire display bounds will be captured. + */ + public abstract void captureDisplay(int displayId, + @Nullable ScreenCapture.CaptureArgs captureArgs, + ScreenCapture.ScreenCaptureListener listener); + + /** * Device has a software navigation bar (separate from the status bar) on specific display. * * @param displayId the id of display to check if there is a software navigation bar. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 809e2d0dcb85..08acd24ffe7c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1972,7 +1972,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - void removeWindow(Session session, IWindow client) { + void removeClientToken(Session session, IBinder client) { synchronized (mGlobalLock) { WindowState win = windowForClientLocked(session, client, false); if (win != null) { @@ -8529,6 +8529,12 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void captureDisplay(int displayId, @Nullable ScreenCapture.CaptureArgs captureArgs, + ScreenCapture.ScreenCaptureListener listener) { + WindowManagerService.this.captureDisplay(displayId, captureArgs, listener); + } + + @Override public boolean hasNavigationBar(int displayId) { return WindowManagerService.this.hasNavigationBar(displayId); } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 89d47bcf41d5..208df6c768bf 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -63,6 +63,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; +import static com.android.server.wm.ActivityTaskSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_PINNED_TASK; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; @@ -938,7 +939,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub break; } final Task task = wc.asTask(); - task.remove(true, "Applying remove task Hierarchy Op"); + + if (task.isLeafTask()) { + mService.mTaskSupervisor + .removeTask(task, true, REMOVE_FROM_RECENTS, "remove-task" + + "-through-hierarchyOp"); + } else { + mService.mTaskSupervisor.removeRootTask(task); + } break; } case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: { diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index a74a707d5ef9..558bf9d6310a 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -1666,7 +1666,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio private void scheduleClientTransactionItem(@NonNull IApplicationThread thread, @NonNull ClientTransactionItem transactionItem) { try { - mAtm.getLifecycleManager().scheduleTransaction(thread, transactionItem); + mAtm.getLifecycleManager().scheduleTransactionItem(thread, transactionItem); } catch (Exception e) { Slog.e(TAG_CONFIGURATION, "Failed to schedule ClientTransactionItem=" + transactionItem + " owner=" + mOwner, e); @@ -1864,6 +1864,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio } @HotPath(caller = HotPath.OOM_ADJUSTMENT) + public boolean isShowingUiWhileDozing() { + return this == mAtm.mVisibleDozeUiProcess; + } + + @HotPath(caller = HotPath.OOM_ADJUSTMENT) public boolean isPreviousProcess() { return this == mAtm.mPreviousProcess; } diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt index 26ea9d24f918..f94a0d664a69 100644 --- a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt +++ b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt @@ -145,16 +145,6 @@ class AppOpService(private val service: AccessCheckingService) : AppOpsCheckingS opSparseArray } - override fun areUidModesDefault(uid: Int): Boolean { - val modes = getUidModes(uid) - return modes == null || modes.isEmpty() - } - - override fun arePackageModesDefault(packageName: String, userId: Int): Boolean { - val modes = service.getState { getPackageModes(packageName, userId) } - return modes == null || modes.isEmpty() - } - override fun clearAllModes() { // We don't need to implement this because it's only called in AppOpsService#readState // and we have our own persistence. diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt index 010604f9aaaa..02032c786563 100644 --- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt @@ -1706,7 +1706,7 @@ class AppIdPermissionPolicy : SchemePolicy() { } /** Listener for permission flags changes. */ - abstract class OnPermissionFlagsChangedListener { + interface OnPermissionFlagsChangedListener { /** * Called when a permission flags change has been made to the upcoming new state. * @@ -1714,7 +1714,7 @@ class AppIdPermissionPolicy : SchemePolicy() { * and only call external code after [onStateMutated] when the new state has actually become * the current state visible to external code. */ - abstract fun onPermissionFlagsChanged( + fun onPermissionFlagsChanged( appId: Int, userId: Int, permissionName: String, @@ -1727,6 +1727,6 @@ class AppIdPermissionPolicy : SchemePolicy() { * * Implementations should keep this method fast to avoid stalling the locked state mutation. */ - abstract fun onStateMutated() + fun onStateMutated() } } diff --git a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt index 7db09f9125de..bb68bc5c791d 100644 --- a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt +++ b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt @@ -263,10 +263,6 @@ class DevicePermissionPolicy : SchemePolicy() { synchronized(listenersLock) { listeners = listeners + listener } } - fun removeOnPermissionFlagsChangedListener(listener: OnDevicePermissionFlagsChangedListener) { - synchronized(listenersLock) { listeners = listeners - listener } - } - private fun isDeviceAwarePermission(permissionName: String): Boolean = DEVICE_AWARE_PERMISSIONS.contains(permissionName) @@ -283,11 +279,8 @@ class DevicePermissionPolicy : SchemePolicy() { } } - /** - * TODO: b/289355341 - implement listener for permission changes Listener for permission flags - * changes. - */ - abstract class OnDevicePermissionFlagsChangedListener { + /** Listener for permission flags changes. */ + interface OnDevicePermissionFlagsChangedListener { /** * Called when a permission flags change has been made to the upcoming new state. * @@ -295,7 +288,7 @@ class DevicePermissionPolicy : SchemePolicy() { * and only call external code after [onStateMutated] when the new state has actually become * the current state visible to external code. */ - abstract fun onDevicePermissionFlagsChanged( + fun onDevicePermissionFlagsChanged( appId: Int, userId: Int, deviceId: String, @@ -309,6 +302,6 @@ class DevicePermissionPolicy : SchemePolicy() { * * Implementations should keep this method fast to avoid stalling the locked state mutation. */ - abstract fun onStateMutated() + fun onStateMutated() } } diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt index ab3d78c9958c..0d196b48b3f2 100644 --- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt +++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt @@ -19,6 +19,7 @@ package com.android.server.permission.access.permission import android.Manifest import android.app.ActivityManager import android.app.AppOpsManager +import android.companion.virtual.VirtualDeviceManager import android.compat.annotation.ChangeId import android.compat.annotation.EnabledAfter import android.content.Context @@ -169,6 +170,7 @@ class PermissionService(private val service: AccessCheckingService) : onPermissionsChangeListeners = OnPermissionsChangeListeners(FgThread.get().looper) onPermissionFlagsChangedListener = OnPermissionFlagsChangedListener() policy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener) + devicePolicy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener) } override fun getAllPermissionGroups(flags: Int): List<PermissionGroupInfo> { @@ -2616,10 +2618,11 @@ class PermissionService(private val service: AccessCheckingService) : /** Callback invoked when interesting actions have been taken on a permission. */ private inner class OnPermissionFlagsChangedListener : - AppIdPermissionPolicy.OnPermissionFlagsChangedListener() { + AppIdPermissionPolicy.OnPermissionFlagsChangedListener, + DevicePermissionPolicy.OnDevicePermissionFlagsChangedListener { private var isPermissionFlagsChanged = false - private val runtimePermissionChangedUids = MutableIntSet() + private val runtimePermissionChangedUidDevices = MutableIntMap<MutableSet<String>>() // Mapping from UID to whether only notifications permissions are revoked. private val runtimePermissionRevokedUids = SparseBooleanArray() private val gidsChangedUids = MutableIntSet() @@ -2642,6 +2645,24 @@ class PermissionService(private val service: AccessCheckingService) : oldFlags: Int, newFlags: Int ) { + onDevicePermissionFlagsChanged( + appId, + userId, + VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, + permissionName, + oldFlags, + newFlags + ) + } + + override fun onDevicePermissionFlagsChanged( + appId: Int, + userId: Int, + deviceId: String, + permissionName: String, + oldFlags: Int, + newFlags: Int + ) { isPermissionFlagsChanged = true val uid = UserHandle.getUid(userId, appId) @@ -2655,12 +2676,12 @@ class PermissionService(private val service: AccessCheckingService) : // permission flags have changed for a non-runtime permission, now we no longer do // that because permission flags are only for runtime permissions and the listeners // aren't being notified of non-runtime permission grant state changes anyway. - runtimePermissionChangedUids += uid if (wasPermissionGranted && !isPermissionGranted) { runtimePermissionRevokedUids[uid] = permissionName in NOTIFICATIONS_PERMISSIONS && runtimePermissionRevokedUids.get(uid, true) } + runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId } if (permission.hasGids && !wasPermissionGranted && isPermissionGranted) { @@ -2674,10 +2695,12 @@ class PermissionService(private val service: AccessCheckingService) : isPermissionFlagsChanged = false } - runtimePermissionChangedUids.forEachIndexed { _, uid -> - onPermissionsChangeListeners.onPermissionsChanged(uid) + runtimePermissionChangedUidDevices.forEachIndexed { _, uid, deviceIds -> + deviceIds.forEach { deviceId -> + onPermissionsChangeListeners.onPermissionsChanged(uid, deviceId) + } } - runtimePermissionChangedUids.clear() + runtimePermissionChangedUidDevices.clear() if (!isKillRuntimePermissionRevokedUidsSkipped) { val reason = @@ -2749,15 +2772,16 @@ class PermissionService(private val service: AccessCheckingService) : when (msg.what) { MSG_ON_PERMISSIONS_CHANGED -> { val uid = msg.arg1 - handleOnPermissionsChanged(uid) + val deviceId = msg.obj as String + handleOnPermissionsChanged(uid, deviceId) } } } - private fun handleOnPermissionsChanged(uid: Int) { + private fun handleOnPermissionsChanged(uid: Int, deviceId: String) { listeners.broadcast { listener -> try { - listener.onPermissionsChanged(uid) + listener.onPermissionsChanged(uid, deviceId) } catch (e: RemoteException) { Slog.e(LOG_TAG, "Error when calling OnPermissionsChangeListener", e) } @@ -2772,9 +2796,9 @@ class PermissionService(private val service: AccessCheckingService) : listeners.unregister(listener) } - fun onPermissionsChanged(uid: Int) { + fun onPermissionsChanged(uid: Int, deviceId: String) { if (listeners.registeredCallbackCount > 0) { - obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget() + obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget() } } diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java index b63a58a96b8c..21342783b79c 100644 --- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java +++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java @@ -25,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; import android.app.Instrumentation; import android.content.Context; @@ -48,6 +49,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import com.android.apps.inputmethod.simpleime.ims.InputMethodServiceWrapper; import com.android.apps.inputmethod.simpleime.testing.TestActivity; +import com.android.internal.inputmethod.InputMethodNavButtonFlags; import org.junit.After; import org.junit.Before; @@ -635,6 +637,82 @@ public class InputMethodServiceTest { .getRootWindowInsets().getInsetsIgnoringVisibility(captionBar())); } + /** + * This checks that trying to show and hide the navigation bar takes effect + * when the IME does draw the IME navigation bar. + */ + @Test + public void testShowHideImeNavigationBar_doesDrawImeNavBar() throws Exception { + boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService() + .hasNavigationBar(mInputMethodService.getDisplayId()); + assumeTrue("Must have a navigation bar", hasNavigationBar); + + setShowImeWithHardKeyboard(true /* enabled */); + + // Show IME + verifyInputViewStatusOnMainSync( + () -> { + mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged( + InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR + | InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN + ); + assertThat(mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(); + }, + true /* expected */, + true /* inputViewStarted */); + assertThat(mInputMethodService.isInputViewShown()).isTrue(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isTrue(); + + // Try to hide IME nav bar + mInstrumentation.runOnMainSync(() -> mInputMethodService.getWindow().getWindow() + .getInsetsController().hide(captionBar())); + mInstrumentation.waitForIdleSync(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse(); + + // Try to show IME nav bar + mInstrumentation.runOnMainSync(() -> mInputMethodService.getWindow().getWindow() + .getInsetsController().show(captionBar())); + mInstrumentation.waitForIdleSync(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isTrue(); + } + /** + * This checks that trying to show and hide the navigation bar has no effect + * when the IME does not draw the IME navigation bar. + * + * Note: The IME navigation bar is *never* visible in 3 button navigation mode. + */ + @Test + public void testShowHideImeNavigationBar_doesNotDrawImeNavBar() throws Exception { + boolean hasNavigationBar = WindowManagerGlobal.getWindowManagerService() + .hasNavigationBar(mInputMethodService.getDisplayId()); + assumeTrue("Must have a navigation bar", hasNavigationBar); + + setShowImeWithHardKeyboard(true /* enabled */); + + // Show IME + verifyInputViewStatusOnMainSync(() -> { + mInputMethodService.getInputMethodInternal().onNavButtonFlagsChanged( + 0 /* navButtonFlags */); + assertThat(mActivity.showImeWithInputMethodManager(0 /* flags */)).isTrue(); + }, + true /* expected */, + true /* inputViewStarted */); + assertThat(mInputMethodService.isInputViewShown()).isTrue(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse(); + + // Try to hide IME nav bar + mInstrumentation.runOnMainSync(() -> mInputMethodService.getWindow().getWindow() + .getInsetsController().hide(captionBar())); + mInstrumentation.waitForIdleSync(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse(); + + // Try to show IME nav bar + mInstrumentation.runOnMainSync(() -> mInputMethodService.getWindow().getWindow() + .getInsetsController().show(captionBar())); + mInstrumentation.waitForIdleSync(); + assertThat(mInputMethodService.isImeNavigationBarShownForTesting()).isFalse(); + } + private void verifyInputViewStatus( Runnable runnable, boolean expected, boolean inputViewStarted) throws InterruptedException { diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index edab1d649ac6..170faf61858b 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -270,7 +270,8 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::getMinAspectRatio, AndroidPackage::hasPreserveLegacyExternalStorage, AndroidPackage::hasRequestForegroundServiceExemption, - AndroidPackage::hasRequestRawExternalStorageAccess + AndroidPackage::hasRequestRawExternalStorageAccess, + AndroidPackage::isUpdatableSystem ) override fun extraParams() = listOf( diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java index 1e65c89643fd..a9f5b14fc48d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java @@ -182,6 +182,10 @@ public class PackageArchiverTest { when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getResourcesForApplication(eq(PACKAGE))).thenReturn( mock(Resources.class)); + when(mInstallerService.createSessionInternal(any(), any(), any(), anyInt(), + anyInt())).thenReturn(1); + when(mInstallerService.getExistingDraftSessionId(anyInt(), any(), anyInt())).thenReturn( + PackageInstaller.SessionInfo.INVALID_ID); doReturn(new ParceledListSlice<>(List.of(mock(ResolveInfo.class)))) .when(mPackageManagerService).queryIntentReceivers(any(), any(), any(), anyLong(), eq(mUserId)); @@ -475,6 +479,7 @@ public class PackageArchiverTest { /* initialExtras= */ isNull()); Intent intent = intentCaptor.getValue(); assertThat(intent.getFlags() & FLAG_RECEIVER_FOREGROUND).isNotEqualTo(0); + assertThat(intent.getIntExtra(PackageInstaller.EXTRA_UNARCHIVE_ID, -1)).isEqualTo(1); assertThat(intent.getStringExtra(PackageInstaller.EXTRA_UNARCHIVE_PACKAGE_NAME)).isEqualTo( PACKAGE); assertThat( diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java index a2e7cf3f1bb2..fd2cf6d4bb5f 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java @@ -55,6 +55,10 @@ import android.os.Message; import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; +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.testing.TestableContext; import android.util.DebugUtils; @@ -69,6 +73,7 @@ import com.android.internal.util.ConcurrentUtils; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.AccessibilityTraceManager; import com.android.server.accessibility.EventStreamTransformation; +import com.android.server.accessibility.Flags; import com.android.server.accessibility.magnification.FullScreenMagnificationController.MagnificationInfoChangedCallback; import com.android.server.testutils.OffsettableClock; import com.android.server.testutils.TestHandler; @@ -134,6 +139,9 @@ import java.util.function.IntConsumer; @RunWith(AndroidJUnit4.class) public class FullScreenMagnificationGestureHandlerTest { + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + public static final int STATE_IDLE = 1; public static final int STATE_ACTIVATED = 2; public static final int STATE_SHORTCUT_TRIGGERED = 3; @@ -425,6 +433,7 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test + @RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) public void testDisablingTripleTap_removesInputLag() { mMgh = newInstance(/* detectSingleFingerTripleTap */ false, /* detectTwoFingerTripleTap */ true, /* detectShortcut */ true); @@ -436,6 +445,18 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void testDisablingSingleFingerTripleTapAndTwoFingerTripleTap_removesInputLag() { + mMgh = newInstance(/* detectSingleFingerTripleTap */ false, + /* detectTwoFingerTripleTap */ false, /* detectShortcut */ true); + goFromStateIdleTo(STATE_IDLE); + allowEventDelegation(); + tap(); + // no fast forward + verify(mMgh.getNext(), times(2)).onMotionEvent(any(), any(), anyInt()); + } + + @Test public void testLongTapAfterShortcutTriggered_neverLogMagnificationTripleTap() { goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED); @@ -510,6 +531,54 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void testTwoFingerTripleTap_StateIsIdle_shouldInActivated() { + goFromStateIdleTo(STATE_IDLE); + + twoFingerTap(); + twoFingerTap(); + twoFingerTap(); + + assertIn(STATE_ACTIVATED); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void testTwoFingerTripleTap_StateIsActivated_shouldInIdle() { + goFromStateIdleTo(STATE_ACTIVATED); + + twoFingerTap(); + twoFingerTap(); + twoFingerTap(); + + assertIn(STATE_IDLE); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void testTwoFingerTripleTapAndHold_StateIsIdle_shouldZoomsImmediately() { + goFromStateIdleTo(STATE_IDLE); + + twoFingerTap(); + twoFingerTap(); + twoFingerTapAndHold(); + + assertIn(STATE_NON_ACTIVATED_ZOOMED_TMP); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void testTwoFingerTripleSwipeAndHold_StateIsIdle_shouldZoomsImmediately() { + goFromStateIdleTo(STATE_IDLE); + + twoFingerTap(); + twoFingerTap(); + twoFingerSwipeAndHold(); + + assertIn(STATE_NON_ACTIVATED_ZOOMED_TMP); + } + + @Test public void testMultiTap_outOfDistanceSlop_shouldInIdle() { // All delay motion events should be sent, if multi-tap with out of distance slop. // STATE_IDLE will check if tapCount() < 2. @@ -1258,6 +1327,30 @@ public class FullScreenMagnificationGestureHandlerTest { send(upEvent()); } + private void twoFingerTap() { + send(downEvent()); + send(pointerEvent(ACTION_POINTER_DOWN, DEFAULT_X * 2, DEFAULT_Y)); + send(pointerEvent(ACTION_POINTER_UP, DEFAULT_X * 2, DEFAULT_Y)); + send(upEvent()); + } + + private void twoFingerTapAndHold() { + send(downEvent()); + send(pointerEvent(ACTION_POINTER_DOWN, DEFAULT_X * 2, DEFAULT_Y)); + fastForward(2000); + } + + private void twoFingerSwipeAndHold() { + PointF pointer1 = DEFAULT_POINT; + PointF pointer2 = new PointF(DEFAULT_X * 1.5f, DEFAULT_Y); + + send(downEvent()); + send(pointerEvent(ACTION_POINTER_DOWN, new PointF[] {pointer1, pointer2}, 1)); + final float sWipeMinDistance = ViewConfiguration.get(mContext).getScaledTouchSlop(); + pointer1.offset(sWipeMinDistance + 1, 0); + send(pointerEvent(ACTION_MOVE, new PointF[] {pointer1, pointer2}, 0)); + } + private void triggerShortcut() { mMgh.notifyShortcutTriggered(); } diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java index 258302354e45..01922e08d71d 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java @@ -57,12 +57,11 @@ public class VirtualCameraControllerTest { private static final int CAMERA_DISPLAY_NAME_RES_ID_1 = 10; private static final int CAMERA_WIDTH_1 = 100; private static final int CAMERA_HEIGHT_1 = 200; - private static final int CAMERA_FORMAT_1 = ImageFormat.RGB_565; private static final int CAMERA_DISPLAY_NAME_RES_ID_2 = 11; private static final int CAMERA_WIDTH_2 = 400; private static final int CAMERA_HEIGHT_2 = 600; - private static final int CAMERA_FORMAT_2 = ImageFormat.YUY2; + private static final int CAMERA_FORMAT = ImageFormat.YUV_420_888; @Mock private IVirtualCameraService mVirtualCameraServiceMock; @@ -81,7 +80,7 @@ public class VirtualCameraControllerTest { @Test public void registerCamera_registersCamera() throws Exception { mVirtualCameraController.registerCamera(createVirtualCameraConfig( - CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_DISPLAY_NAME_RES_ID_1)); + CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_1)); ArgumentCaptor<VirtualCameraConfiguration> configurationCaptor = ArgumentCaptor.forClass(VirtualCameraConfiguration.class); @@ -89,13 +88,13 @@ public class VirtualCameraControllerTest { VirtualCameraConfiguration virtualCameraConfiguration = configurationCaptor.getValue(); assertThat(virtualCameraConfiguration.supportedStreamConfigs.length).isEqualTo(1); assertVirtualCameraConfiguration(virtualCameraConfiguration, CAMERA_WIDTH_1, - CAMERA_HEIGHT_1, CAMERA_FORMAT_1); + CAMERA_HEIGHT_1, CAMERA_FORMAT); } @Test public void unregisterCamera_unregistersCamera() throws Exception { VirtualCameraConfig config = createVirtualCameraConfig( - CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_DISPLAY_NAME_RES_ID_1); + CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_1); mVirtualCameraController.unregisterCamera(config); verify(mVirtualCameraServiceMock).unregisterCamera(any()); @@ -104,9 +103,9 @@ public class VirtualCameraControllerTest { @Test public void close_unregistersAllCameras() throws Exception { mVirtualCameraController.registerCamera(createVirtualCameraConfig( - CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_DISPLAY_NAME_RES_ID_1)); + CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_1)); mVirtualCameraController.registerCamera(createVirtualCameraConfig( - CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT_2, CAMERA_DISPLAY_NAME_RES_ID_2)); + CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT, CAMERA_DISPLAY_NAME_RES_ID_2)); ArgumentCaptor<VirtualCameraConfiguration> configurationCaptor = ArgumentCaptor.forClass(VirtualCameraConfiguration.class); @@ -117,9 +116,9 @@ public class VirtualCameraControllerTest { configurationCaptor.getAllValues(); assertThat(virtualCameraConfigurations).hasSize(2); assertVirtualCameraConfiguration(virtualCameraConfigurations.get(0), CAMERA_WIDTH_1, - CAMERA_HEIGHT_1, CAMERA_FORMAT_1); + CAMERA_HEIGHT_1, CAMERA_FORMAT); assertVirtualCameraConfiguration(virtualCameraConfigurations.get(1), CAMERA_WIDTH_2, - CAMERA_HEIGHT_2, CAMERA_FORMAT_2); + CAMERA_HEIGHT_2, CAMERA_FORMAT); } private VirtualCameraConfig createVirtualCameraConfig( diff --git a/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java b/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java index 949f8e7a6ab0..0e881efd4cdf 100644 --- a/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/net/LockdownVpnTrackerTest.java @@ -221,7 +221,7 @@ public class LockdownVpnTrackerTest { callCallbacksForNetworkConnect(defaultCallback, mNetwork); // Vpn is starting - verify(mVpn).startLegacyVpnPrivileged(mProfile, mNetwork, TEST_CELL_LP); + verify(mVpn).startLegacyVpnPrivileged(mProfile); verify(mNotificationManager).notify(any(), eq(SystemMessage.NOTE_VPN_STATUS), argThat(notification -> isExpectedNotification(notification, R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected))); @@ -242,7 +242,7 @@ public class LockdownVpnTrackerTest { // LockdownVpnTracker#handleStateChangedLocked. This is a bug. // TODO: consider fixing this. verify(mVpn, never()).stopVpnRunnerPrivileged(); - verify(mVpn, never()).startLegacyVpnPrivileged(any(), any(), any()); + verify(mVpn, never()).startLegacyVpnPrivileged(any()); verify(mNotificationManager, never()).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS)); } @@ -302,7 +302,7 @@ public class LockdownVpnTrackerTest { // Vpn is restarted. verify(mVpn).stopVpnRunnerPrivileged(); - verify(mVpn).startLegacyVpnPrivileged(mProfile, mNetwork2, wifiLp); + verify(mVpn).startLegacyVpnPrivileged(mProfile); verify(mNotificationManager, never()).cancel(any(), eq(SystemMessage.NOTE_VPN_STATUS)); verify(mNotificationManager).notify(any(), eq(SystemMessage.NOTE_VPN_STATUS), argThat(notification -> isExpectedNotification(notification, diff --git a/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java index bfd407216c3b..186a27ccdc26 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserJourneyLoggerTest.java @@ -45,6 +45,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.pm.UserInfo; +import android.os.UserManager; import android.platform.test.annotations.Presubmit; import androidx.test.runner.AndroidJUnit4; @@ -135,6 +136,53 @@ public class UserJourneyLoggerTest { } @Test + public void testCreatePrivateProfileUserJourney() { + final UserLifecycleEventOccurredCaptor report1 = new UserLifecycleEventOccurredCaptor(); + final UserJourneyLogger.UserJourneySession session = + mUserJourneyLogger.logUserJourneyBegin(-1, USER_JOURNEY_USER_CREATE); + + report1.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + -1, + USER_LIFECYCLE_EVENT_CREATE_USER, + EVENT_STATE_BEGIN, + ERROR_CODE_UNSPECIFIED, + 1); + + final UserLifecycleJourneyReportedCaptor report2 = new UserLifecycleJourneyReportedCaptor(); + final int profileUserId = 10; + UserInfo targetUser = + new UserInfo( + profileUserId, + "test private target user", + /* iconPath= */ null, + UserInfo.FLAG_PROFILE, + UserManager.USER_TYPE_PROFILE_PRIVATE); + mUserJourneyLogger.logUserCreateJourneyFinish(0, targetUser); + + report1.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + profileUserId, + USER_LIFECYCLE_EVENT_CREATE_USER, + EVENT_STATE_FINISH, + ERROR_CODE_UNSPECIFIED, + 2); + + report2.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + USER_JOURNEY_USER_CREATE, + 0, + profileUserId, + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_PRIVATE, + UserInfo.FLAG_PROFILE, + ERROR_CODE_UNSPECIFIED, + 1); + } + + @Test public void testRemoveUserJourney() { final UserLifecycleEventOccurredCaptor report1 = new UserLifecycleEventOccurredCaptor(); final UserJourneyLogger.UserJourneySession session = mUserJourneyLogger @@ -161,6 +209,54 @@ public class UserJourneyLoggerTest { } @Test + public void testRemovePrivateProfileUserJourneyWithError() { + final UserLifecycleEventOccurredCaptor report1 = new UserLifecycleEventOccurredCaptor(); + final int profileUserId = 10; + final UserJourneyLogger.UserJourneySession session = + mUserJourneyLogger.logUserJourneyBegin(profileUserId, USER_JOURNEY_USER_REMOVE); + + report1.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + profileUserId, + USER_LIFECYCLE_EVENT_REMOVE_USER, + EVENT_STATE_BEGIN, + ERROR_CODE_UNSPECIFIED, + 1); + + final UserLifecycleJourneyReportedCaptor report2 = new UserLifecycleJourneyReportedCaptor(); + final UserInfo targetUser = + new UserInfo( + profileUserId, + "test private target user", + /* iconPath= */ null, + UserInfo.FLAG_PROFILE, + UserManager.USER_TYPE_PROFILE_PRIVATE); + mUserJourneyLogger.logUserJourneyFinishWithError( + 0, targetUser, USER_JOURNEY_USER_REMOVE, ERROR_CODE_INCOMPLETE_OR_TIMEOUT); + + report1.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + profileUserId, + USER_LIFECYCLE_EVENT_REMOVE_USER, + EVENT_STATE_ERROR, + ERROR_CODE_INCOMPLETE_OR_TIMEOUT, + 2); + + report2.captureAndAssert( + mUserJourneyLogger, + session.mSessionId, + USER_JOURNEY_USER_REMOVE, + 0, + profileUserId, + FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_PRIVATE, + UserInfo.FLAG_PROFILE, + ERROR_CODE_INCOMPLETE_OR_TIMEOUT, + 1); + } + + @Test public void testStartUserJourney() { final UserLifecycleEventOccurredCaptor report1 = new UserLifecycleEventOccurredCaptor(); final UserJourneyLogger.UserJourneySession session = mUserJourneyLogger diff --git a/services/tests/timetests/TEST_MAPPING b/services/tests/timetests/TEST_MAPPING index b24010ce447a..e549229d000f 100644 --- a/services/tests/timetests/TEST_MAPPING +++ b/services/tests/timetests/TEST_MAPPING @@ -1,6 +1,5 @@ { - // TODO(b/182461754): Change to "presubmit" when go/test-mapping-slo-guide allows. - "postsubmit": [ + "presubmit": [ { "name": "FrameworksTimeServicesTests" } diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java index 270d5df5e702..ab35da69da7c 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java +++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java @@ -46,7 +46,6 @@ import static com.android.server.policy.WindowManagerPolicy.ACTION_PASS_TO_USER; import static java.util.Collections.unmodifiableMap; import android.content.Context; -import android.os.SystemClock; import android.util.ArrayMap; import android.view.InputDevice; import android.view.KeyCharacterMap; @@ -110,8 +109,8 @@ class ShortcutKeyTestBase { } } - void sendKeyCombination(int[] keyCodes, long duration, boolean longPress) { - final long downTime = SystemClock.uptimeMillis(); + void sendKeyCombination(int[] keyCodes, long durationMillis, boolean longPress) { + final long downTime = mPhoneWindowManager.getCurrentTime(); final int count = keyCodes.length; int metaState = 0; @@ -126,14 +125,12 @@ class ShortcutKeyTestBase { metaState |= MODIFIER.getOrDefault(keyCode, 0); } - try { - Thread.sleep(duration); - } catch (InterruptedException e) { - throw new RuntimeException(e); + if (durationMillis > 0) { + mPhoneWindowManager.moveTimeForward(durationMillis); } if (longPress) { - final long nextDownTime = SystemClock.uptimeMillis(); + final long nextDownTime = mPhoneWindowManager.getCurrentTime(); for (int i = 0; i < count; i++) { final int keyCode = keyCodes[i]; final KeyEvent nextDownEvent = new KeyEvent(downTime, nextDownTime, @@ -145,7 +142,7 @@ class ShortcutKeyTestBase { } } - final long eventTime = SystemClock.uptimeMillis(); + final long eventTime = mPhoneWindowManager.getCurrentTime(); for (int i = count - 1; i >= 0; i--) { final int keyCode = keyCodes[i]; final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode, @@ -157,8 +154,8 @@ class ShortcutKeyTestBase { } } - void sendKeyCombination(int[] keyCodes, long duration) { - sendKeyCombination(keyCodes, duration, false /* longPress */); + void sendKeyCombination(int[] keyCodes, long durationMillis) { + sendKeyCombination(keyCodes, durationMillis, false /* longPress */); } void sendLongPressKeyCombination(int[] keyCodes) { @@ -170,30 +167,7 @@ class ShortcutKeyTestBase { } void sendKey(int keyCode, boolean longPress) { - final long downTime = SystemClock.uptimeMillis(); - final KeyEvent event = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode, - 0 /*repeat*/, 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, - 0 /*flags*/, InputDevice.SOURCE_KEYBOARD); - event.setDisplayId(DEFAULT_DISPLAY); - interceptKey(event); - - if (longPress) { - final long nextDownTime = downTime + ViewConfiguration.getLongPressTimeout(); - final KeyEvent nextDownevent = new KeyEvent(downTime, nextDownTime, - KeyEvent.ACTION_DOWN, keyCode, 1 /*repeat*/, 0 /*metaState*/, - KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, - KeyEvent.FLAG_LONG_PRESS /*flags*/, InputDevice.SOURCE_KEYBOARD); - interceptKey(nextDownevent); - } - - final long eventTime = longPress - ? SystemClock.uptimeMillis() + ViewConfiguration.getLongPressTimeout() - : SystemClock.uptimeMillis(); - final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode, - 0 /*repeat*/, 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, - 0 /*flags*/, InputDevice.SOURCE_KEYBOARD); - upEvent.setDisplayId(DEFAULT_DISPLAY); - interceptKey(upEvent); + sendKeyCombination(new int[]{keyCode}, 0 /*durationMillis*/, longPress); } private void interceptKey(KeyEvent keyEvent) { diff --git a/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java b/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java index f2721a556454..7ea5010976ee 100644 --- a/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/SingleKeyGestureTests.java @@ -30,9 +30,9 @@ import static org.junit.Assert.assertTrue; import android.app.Instrumentation; import android.content.Context; -import android.os.Looper; import android.os.Handler; import android.os.HandlerThread; +import android.os.Looper; import android.os.Process; import android.os.SystemClock; import android.view.KeyEvent; @@ -109,7 +109,7 @@ public class SingleKeyGestureTests { } @Override - public void onPress(long downTime) { + public void onPress(long downTime, int displayId) { if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) { return; } @@ -131,7 +131,7 @@ public class SingleKeyGestureTests { } @Override - void onMultiPress(long downTime, int count) { + void onMultiPress(long downTime, int count, int displayId) { if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) { return; } @@ -141,7 +141,7 @@ public class SingleKeyGestureTests { } @Override - void onKeyUp(long eventTime, int multiPressCount) { + void onKeyUp(long eventTime, int multiPressCount, int displayId) { mKeyUpQueue.add(new KeyUpData(KEYCODE_POWER, multiPressCount)); } }); @@ -159,7 +159,7 @@ public class SingleKeyGestureTests { } @Override - public void onPress(long downTime) { + public void onPress(long downTime, int displayId) { if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) { return; } @@ -167,7 +167,7 @@ public class SingleKeyGestureTests { } @Override - void onMultiPress(long downTime, int count) { + void onMultiPress(long downTime, int count, int displayId) { if (mDetector.beganFromNonInteractive() && !mAllowNonInteractiveForPress) { return; } @@ -177,7 +177,7 @@ public class SingleKeyGestureTests { } @Override - void onKeyUp(long eventTime, int multiPressCount) { + void onKeyUp(long eventTime, int multiPressCount, int displayId) { mKeyUpQueue.add(new KeyUpData(KEYCODE_BACK, multiPressCount)); } @@ -398,7 +398,7 @@ public class SingleKeyGestureTests { final SingleKeyGestureDetector.SingleKeyRule rule = new SingleKeyGestureDetector.SingleKeyRule(KEYCODE_POWER) { @Override - void onPress(long downTime) { + void onPress(long downTime, int displayId) { mShortPressed.countDown(); } }; diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java index 314cd04695ba..7788b339738b 100644 --- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java @@ -99,6 +99,7 @@ import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.keyguard.KeyguardServiceDelegate; import com.android.server.statusbar.StatusBarManagerInternal; +import com.android.server.testutils.OffsettableClock; import com.android.server.vr.VrManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.DisplayPolicy; @@ -162,7 +163,8 @@ class TestPhoneWindowManager { @Mock private KeyguardServiceDelegate mKeyguardServiceDelegate; private StaticMockitoSession mMockitoSession; - private TestLooper mTestLooper = new TestLooper(); + private OffsettableClock mClock = new OffsettableClock(); + private TestLooper mTestLooper = new TestLooper(() -> mClock.now()); private HandlerThread mHandlerThread; private Handler mHandler; @@ -335,6 +337,15 @@ class TestPhoneWindowManager { mPhoneWindowManager.dispatchUnhandledKey(null /*focusedToken*/, event, FLAG_INTERACTIVE); } + long getCurrentTime() { + return mClock.now(); + } + + void moveTimeForward(long timeMs) { + mClock.fastForward(timeMs); + mTestLooper.dispatchAll(); + } + /** * Below functions will override the setting or the policy behavior. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 1776ba556b72..786432a5dc88 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -490,7 +490,7 @@ public class ActivityRecordTests extends WindowTestsBase { ensureActivityConfiguration(activity); verify(mClientLifecycleManager, never()) - .scheduleTransaction(any(), isA(ActivityConfigurationChangeItem.class)); + .scheduleTransactionItem(any(), isA(ActivityConfigurationChangeItem.class)); } @Test @@ -519,7 +519,7 @@ public class ActivityRecordTests extends WindowTestsBase { // The configuration change is still sent to the activity, even if it doesn't relaunch. final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, newConfig); - verify(mClientLifecycleManager).scheduleTransaction( + verify(mClientLifecycleManager).scheduleTransactionItem( eq(activity.app.getThread()), eq(expected)); } @@ -592,7 +592,7 @@ public class ActivityRecordTests extends WindowTestsBase { assertEquals(expectedOrientation, currentConfig.orientation); final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, currentConfig); - verify(mClientLifecycleManager).scheduleTransaction(activity.app.getThread(), expected); + verify(mClientLifecycleManager).scheduleTransactionItem(activity.app.getThread(), expected); verify(displayRotation).onSetRequestedOrientation(); } @@ -812,7 +812,8 @@ public class ActivityRecordTests extends WindowTestsBase { final ActivityConfigurationChangeItem expected = ActivityConfigurationChangeItem.obtain(activity.token, activity.getConfiguration()); - verify(mClientLifecycleManager).scheduleTransaction(activity.app.getThread(), expected); + verify(mClientLifecycleManager).scheduleTransactionItem( + activity.app.getThread(), expected); } finally { stack.getDisplayArea().removeChild(stack); } @@ -1785,7 +1786,7 @@ public class ActivityRecordTests extends WindowTestsBase { clearInvocations(mClientLifecycleManager); activity.getTask().removeImmediately("test"); try { - verify(mClientLifecycleManager).scheduleTransaction(any(), + verify(mClientLifecycleManager).scheduleTransactionItem(any(), isA(DestroyActivityItem.class)); } catch (RemoteException ignored) { } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 3c027ffa5dac..d2c731c3f8ad 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -127,7 +127,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { final ArgumentCaptor<ClientTransactionItem> clientTransactionItemCaptor = ArgumentCaptor.forClass(ClientTransactionItem.class); - verify(mockLifecycleManager).scheduleTransaction(any(), + verify(mockLifecycleManager).scheduleTransactionItem(any(), clientTransactionItemCaptor.capture()); final ClientTransactionItem transactionItem = clientTransactionItemCaptor.getValue(); // Check that only an enter pip request item callback was scheduled. @@ -144,7 +144,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { mAtm.mActivityClientController.requestPictureInPictureMode(activity); - verify(mClientLifecycleManager, never()).scheduleTransaction(any(), any()); + verify(mClientLifecycleManager, never()).scheduleTransactionItem(any(), any()); } @Test @@ -156,7 +156,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { mAtm.mActivityClientController.requestPictureInPictureMode(activity); - verify(mClientLifecycleManager, never()).scheduleTransaction(any(), any()); + verify(mClientLifecycleManager, never()).scheduleTransactionItem(any(), any()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java index a18dbaf39575..04aa9815e698 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java @@ -16,18 +16,32 @@ package com.android.server.wm; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; + import android.app.IApplicationThread; +import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ClientTransaction; +import android.app.servertransaction.ClientTransactionItem; +import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; +import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; /** * Build/Install/Run: @@ -37,23 +51,77 @@ import org.junit.Test; @Presubmit public class ClientLifecycleManagerTests { + @Mock + private IApplicationThread mClient; + @Mock + private IApplicationThread.Stub mNonBinderClient; + @Mock + private ClientTransactionItem mTransactionItem; + @Mock + private ActivityLifecycleItem mLifecycleItem; + @Captor + private ArgumentCaptor<ClientTransaction> mTransactionCaptor; + + private ClientLifecycleManager mLifecycleManager; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + mLifecycleManager = spy(new ClientLifecycleManager()); + + doReturn(true).when(mLifecycleItem).isActivityLifecycleItem(); + } + @Test - public void testScheduleAndRecycleBinderClientTransaction() throws Exception { - ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.class))); + public void testScheduleTransaction_recycleBinderClientTransaction() throws Exception { + final ClientTransaction item = spy(ClientTransaction.obtain(mClient)); - ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager(); - clientLifecycleManager.scheduleTransaction(item); + mLifecycleManager.scheduleTransaction(item); - verify(item, times(1)).recycle(); + verify(item).recycle(); } @Test - public void testScheduleNoRecycleNonBinderClientTransaction() throws Exception { - ClientTransaction item = spy(ClientTransaction.obtain(mock(IApplicationThread.Stub.class))); + public void testScheduleTransaction_notRecycleNonBinderClientTransaction() throws Exception { + final ClientTransaction item = spy(ClientTransaction.obtain(mNonBinderClient)); - ClientLifecycleManager clientLifecycleManager = new ClientLifecycleManager(); - clientLifecycleManager.scheduleTransaction(item); + mLifecycleManager.scheduleTransaction(item); + + verify(item, never()).recycle(); + } + + @Test + public void testScheduleTransactionItem() throws RemoteException { + doNothing().when(mLifecycleManager).scheduleTransaction(any()); + mLifecycleManager.scheduleTransactionItem(mClient, mTransactionItem); + + verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture()); + ClientTransaction transaction = mTransactionCaptor.getValue(); + assertEquals(1, transaction.getCallbacks().size()); + assertEquals(mTransactionItem, transaction.getCallbacks().get(0)); + assertNull(transaction.getLifecycleStateRequest()); + assertNull(transaction.getTransactionItems()); + + clearInvocations(mLifecycleManager); + mLifecycleManager.scheduleTransactionItem(mClient, mLifecycleItem); + + verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture()); + transaction = mTransactionCaptor.getValue(); + assertNull(transaction.getCallbacks()); + assertEquals(mLifecycleItem, transaction.getLifecycleStateRequest()); + } + + @Test + public void testScheduleTransactionAndLifecycleItems() throws RemoteException { + doNothing().when(mLifecycleManager).scheduleTransaction(any()); + mLifecycleManager.scheduleTransactionAndLifecycleItems(mClient, mTransactionItem, + mLifecycleItem); - verify(item, times(0)).recycle(); + verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture()); + final ClientTransaction transaction = mTransactionCaptor.getValue(); + assertEquals(1, transaction.getCallbacks().size()); + assertEquals(mTransactionItem, transaction.getCallbacks().get(0)); + assertEquals(mLifecycleItem, transaction.getLifecycleStateRequest()); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 5b88c8cbec92..c6fa8a1b5a98 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -643,6 +643,21 @@ public class DisplayContentTests extends WindowTestsBase { } @Test + public void testDisplayHasContent() { + final WindowState window = createWindow(null, TYPE_APPLICATION_OVERLAY, "window"); + setDrawnState(WindowStateAnimator.COMMIT_DRAW_PENDING, window); + assertFalse(mDisplayContent.getLastHasContent()); + // The pending draw state should be committed and the has-content state is also updated. + mDisplayContent.applySurfaceChangesTransaction(); + assertTrue(window.isDrawn()); + assertTrue(mDisplayContent.getLastHasContent()); + // If the only window is no longer visible, has-content will be false. + setDrawnState(WindowStateAnimator.NO_SURFACE, window); + mDisplayContent.applySurfaceChangesTransaction(); + assertFalse(mDisplayContent.getLastHasContent()); + } + + @Test public void testImeIsAttachedToDisplayForLetterboxedApp() { final DisplayContent dc = mDisplayContent; final WindowState ws = createWindow(null, TYPE_APPLICATION, dc, "app window"); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index c782d3e90e96..be96e60917a3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -274,6 +274,26 @@ public class DisplayPolicyTests extends WindowTestsBase { assertEquals(mAppWindow, policy.getTopFullscreenOpaqueWindow()); } + @SetupWindows(addWindows = W_NOTIFICATION_SHADE) + @Test + public void testVisibleProcessWhileDozing() { + final WindowProcessController wpc = mNotificationShadeWindow.getProcess(); + final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); + policy.addWindowLw(mNotificationShadeWindow, mNotificationShadeWindow.mAttrs); + + policy.screenTurnedOff(); + policy.setAwake(false); + policy.screenTurnedOn(null /* screenOnListener */); + assertTrue(wpc.isShowingUiWhileDozing()); + policy.screenTurnedOff(); + assertFalse(wpc.isShowingUiWhileDozing()); + + policy.screenTurnedOn(null /* screenOnListener */); + assertTrue(wpc.isShowingUiWhileDozing()); + policy.setAwake(true); + assertFalse(wpc.isShowingUiWhileDozing()); + } + @Test(expected = IllegalArgumentException.class) public void testMainAppWindowDisallowFitSystemWindowTypes() { final DisplayPolicy policy = mDisplayContent.getDisplayPolicy(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java index 2af67452283b..e7ac33fc6a1a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java @@ -43,12 +43,9 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.RefreshCallbackItem; import android.app.servertransaction.ResumeActivityItem; import android.content.ComponentName; @@ -529,8 +526,8 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase { public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); - when(mActivity.mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat()) - .thenReturn(true); + doReturn(true).when(mActivity.mLetterboxUiController) + .shouldRefreshActivityViaPauseForCameraCompat(); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); @@ -571,14 +568,14 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase { verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0)) .setIsRefreshAfterRotationRequested(true); - final ClientTransaction transaction = ClientTransaction.obtain(mActivity.app.getThread()); - transaction.addCallback(RefreshCallbackItem.obtain(mActivity.token, - cycleThroughStop ? ON_STOP : ON_PAUSE)); - transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(mActivity.token, - /* isForward */ false, /* shouldSendCompatFakeFocus */ false)); + final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token, + cycleThroughStop ? ON_STOP : ON_PAUSE); + final ResumeActivityItem resumeActivityItem = ResumeActivityItem.obtain(mActivity.token, + /* isForward */ false, /* shouldSendCompatFakeFocus */ false); verify(mActivity.mAtmService.getLifecycleManager(), times(refreshRequested ? 1 : 0)) - .scheduleTransaction(eq(transaction)); + .scheduleTransactionAndLifecycleItems(mActivity.app.getThread(), + refreshCallbackItem, resumeActivityItem); } private void assertNoForceRotationOrRefresh() throws Exception { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java index 013be2587d76..5e531b4cbc4f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java @@ -574,6 +574,7 @@ public class TaskTests extends WindowTestsBase { spyOn(root); spyOn(root.mLetterboxUiController); + doReturn(true).when(root).fillsParent(); doReturn(true).when(root.mLetterboxUiController) .shouldEnableUserAspectRatioSettings(); doReturn(false).when(root).inSizeCompatMode(); @@ -596,6 +597,12 @@ public class TaskTests extends WindowTestsBase { assertFalse(task.getTaskInfo() .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton); doReturn(false).when(root).inSizeCompatMode(); + + // When the top activity is transparent, the button is not enabled + doReturn(false).when(root).fillsParent(); + assertFalse(task.getTaskInfo() + .appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton); + doReturn(true).when(root).fillsParent(); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java index 46cff8b82c6d..e152feb141e1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java @@ -306,7 +306,7 @@ public class WindowProcessControllerTests extends WindowTestsBase { @Test public void testCachedStateConfigurationChange() throws RemoteException { - doNothing().when(mClientLifecycleManager).scheduleTransaction(any(), any()); + doNothing().when(mClientLifecycleManager).scheduleTransactionItem(any(), any()); final IApplicationThread thread = mWpc.getThread(); final Configuration newConfig = new Configuration(mWpc.getConfiguration()); newConfig.densityDpi += 100; @@ -314,20 +314,20 @@ public class WindowProcessControllerTests extends WindowTestsBase { mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); clearInvocations(mClientLifecycleManager); mWpc.onConfigurationChanged(newConfig); - verify(mClientLifecycleManager).scheduleTransaction(eq(thread), any()); + verify(mClientLifecycleManager).scheduleTransactionItem(eq(thread), any()); // Cached state won't send the change. clearInvocations(mClientLifecycleManager); mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); newConfig.densityDpi += 100; mWpc.onConfigurationChanged(newConfig); - verify(mClientLifecycleManager, never()).scheduleTransaction(eq(thread), any()); + verify(mClientLifecycleManager, never()).scheduleTransactionItem(eq(thread), any()); // Cached -> non-cached will send the previous deferred config immediately. mWpc.setReportedProcState(ActivityManager.PROCESS_STATE_RECEIVER); final ArgumentCaptor<ConfigurationChangeItem> captor = ArgumentCaptor.forClass(ConfigurationChangeItem.class); - verify(mClientLifecycleManager).scheduleTransaction(eq(thread), captor.capture()); + verify(mClientLifecycleManager).scheduleTransactionItem(eq(thread), captor.capture()); final ClientTransactionHandler client = mock(ClientTransactionHandler.class); captor.getValue().preExecute(client); final ArgumentCaptor<Configuration> configCaptor = diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index 67384b2d9e18..d8a9a282a622 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -1369,7 +1369,7 @@ public class WindowStateTests extends WindowTestsBase { assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse(); // Scenario 3: test removeWindow to remove the Ime layering target overlay window. - mWm.removeWindow(session, client); + mWm.removeClientToken(session, client.asBinder()); waitHandlerIdle(mWm.mH); assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder()); diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 2975e1e050f5..fc7c6a6d0258 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -1231,6 +1231,26 @@ public class UsbPortManager implements IBinder.DeathRecipient { complianceWarningsProto.add(FrameworkStatsLog .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_MISSING_RP); continue; + case UsbPortStatus.COMPLIANCE_WARNING_INPUT_POWER_LIMITED: + complianceWarningsProto.add(FrameworkStatsLog + .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_INPUT_POWER_LIMITED); + continue; + case UsbPortStatus.COMPLIANCE_WARNING_MISSING_DATA_LINES: + complianceWarningsProto.add(FrameworkStatsLog + .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_MISSING_DATA_LINES); + continue; + case UsbPortStatus.COMPLIANCE_WARNING_ENUMERATION_FAIL: + complianceWarningsProto.add(FrameworkStatsLog + .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_ENUMERATION_FAIL); + continue; + case UsbPortStatus.COMPLIANCE_WARNING_FLAKY_CONNECTION: + complianceWarningsProto.add(FrameworkStatsLog + .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_FLAKY_CONNECTION); + continue; + case UsbPortStatus.COMPLIANCE_WARNING_UNRELIABLE_IO: + complianceWarningsProto.add(FrameworkStatsLog + .USB_COMPLIANCE_WARNINGS_REPORTED__COMPLIANCE_WARNINGS__COMPLIANCE_WARNING_UNRELIABLE_IO); + continue; } } return complianceWarningsProto.toArray(); diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index f3dfcd7db8e3..13a045858ab1 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -384,14 +384,8 @@ public abstract class InCallService extends Service { /** Manages the binder calls so that the implementor does not need to deal with it. */ private final class InCallServiceBinder extends IInCallService.Stub { - private boolean mInCallAdapterSet; @Override public void setInCallAdapter(IInCallAdapter inCallAdapter) { - if (mInCallAdapterSet) { - Log.i(this, "setInCallAdapter: InCallAdapter already set, skipping..."); - return; - } - mInCallAdapterSet = true; mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget(); } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index edd659755c8d..50590177f791 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -546,6 +546,8 @@ public interface RILConstants { int RIL_REQUEST_IS_NULL_CIPHER_AND_INTEGRITY_ENABLED = 245; int RIL_REQUEST_IS_CELLULAR_IDENTIFIER_DISCLOSED_ENABLED = 246; int RIL_REQUEST_SET_CELLULAR_IDENTIFIER_DISCLOSED_ENABLED = 247; + int RIL_REQUEST_SET_SECURITY_ALGORITHMS_UPDATED_ENABLED = 248; + int RIL_REQUEST_IS_SECURITY_ALGORITHMS_UPDATED_ENABLED = 249; /* Responses begin */ int RIL_RESPONSE_ACKNOWLEDGEMENT = 800; @@ -608,6 +610,7 @@ public interface RILConstants { int RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED = 1054; int RIL_UNSOL_SLICING_CONFIG_CHANGED = 1055; int RIL_UNSOL_CELLULAR_IDENTIFIER_DISCLOSED = 1056; + int RIL_UNSOL_SECURITY_ALGORITHMS_UPDATED = 1057; /* The following unsols are not defined in RIL.h */ int RIL_UNSOL_HAL_NON_RIL_BASE = 1100; |