diff options
297 files changed, 3431 insertions, 1050 deletions
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb new file mode 100644 index 000000000000..29bcfe046b98 --- /dev/null +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShimPriv_apk.asciipb @@ -0,0 +1,12 @@ +drops { + android_build_drop { + build_id: "6508977" + target: "CtsShim" + source_file: "aosp_arm64/CtsShimPriv.apk" + } + dest_file: "packages/CtsShim/apk//arm/CtsShimPriv.apk" + version: "" + version_group: "" + git_project: "platform/frameworks/base" + git_branch: "rvc-dev" +} diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb new file mode 100644 index 000000000000..be172e6122cf --- /dev/null +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__arm_CtsShim_apk.asciipb @@ -0,0 +1,12 @@ +drops { + android_build_drop { + build_id: "6508977" + target: "CtsShim" + source_file: "aosp_arm64/CtsShim.apk" + } + dest_file: "packages/CtsShim/apk//arm/CtsShim.apk" + version: "" + version_group: "" + git_project: "platform/frameworks/base" + git_branch: "rvc-dev" +} diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb new file mode 100644 index 000000000000..13eca13c9308 --- /dev/null +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShimPriv_apk.asciipb @@ -0,0 +1,12 @@ +drops { + android_build_drop { + build_id: "6508977" + target: "CtsShim" + source_file: "aosp_x86_64/CtsShimPriv.apk" + } + dest_file: "packages/CtsShim/apk//x86/CtsShimPriv.apk" + version: "" + version_group: "" + git_project: "platform/frameworks/base" + git_branch: "rvc-dev" +} diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb new file mode 100644 index 000000000000..2e863fe57f3c --- /dev/null +++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__x86_CtsShim_apk.asciipb @@ -0,0 +1,12 @@ +drops { + android_build_drop { + build_id: "6508977" + target: "CtsShim" + source_file: "aosp_x86_64/CtsShim.apk" + } + dest_file: "packages/CtsShim/apk//x86/CtsShim.apk" + version: "" + version_group: "" + git_project: "platform/frameworks/base" + git_branch: "rvc-dev" +} diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java index 0647d8a18e49..483d2cc2ec57 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java @@ -67,9 +67,9 @@ import java.util.function.Consumer; * <pre class="prettyprint"> * final long sessionId = blobStoreManager.createSession(blobHandle); * try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) { - * try (ParcelFileDescriptor pfd = new ParcelFileDescriptor.AutoCloseOutputStream( + * try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream( * session.openWrite(offsetBytes, lengthBytes))) { - * writeData(pfd); + * writeData(out); * } * } * </pre> @@ -100,9 +100,9 @@ import java.util.function.Consumer; * <p> The following code snippet shows how to specify the access mode and commit the session: * <pre class="prettyprint"> * try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) { - * try (ParcelFileDescriptor pfd = new ParcelFileDescriptor.AutoCloseOutputStream( + * try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream( * session.openWrite(offsetBytes, lengthBytes))) { - * writeData(pfd); + * writeData(out); * } * session.allowSameSignatureAccess(); * session.allowPackageAccess(packageName, certificate); @@ -134,9 +134,9 @@ import java.util.function.Consumer; * * <p> The following code snippet shows how to access the data blob: * <pre class="prettyprint"> - * try (ParcelFileDescriptor pfd = new ParcelFileDescriptor.AutoCloseInputStream( + * try (InputStream in = new ParcelFileDescriptor.AutoCloseInputStream( * blobStoreManager.openBlob(blobHandle)) { - * useData(pfd); + * useData(in); * } * </pre> */ diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java index 35a2436702da..9376198b8eaf 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -25,6 +25,7 @@ import static android.app.blob.XmlTags.TAG_SESSIONS; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; +import static android.os.UserHandle.USER_CURRENT; import static android.os.UserHandle.USER_NULL; import static com.android.server.blob.BlobStoreConfig.LOGV; @@ -46,6 +47,8 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.blob.BlobHandle; import android.app.blob.BlobInfo; import android.app.blob.IBlobStoreManager; @@ -1378,7 +1381,14 @@ public class BlobStoreManagerService extends SystemService { + "queryBlobsForUser()"); } - return queryBlobsForUserInternal(userId); + final int resolvedUserId = userId == USER_CURRENT + ? ActivityManager.getCurrentUser() : userId; + // Don't allow any other special user ids apart from USER_CURRENT + final ActivityManagerInternal amInternal = LocalServices.getService( + ActivityManagerInternal.class); + amInternal.ensureNotSpecialUser(resolvedUserId); + + return queryBlobsForUserInternal(resolvedUserId); } @Override @@ -1479,12 +1489,13 @@ public class BlobStoreManagerService extends SystemService { private static final int FLAG_DUMP_CONFIG = 1 << 2; private int mSelectedSectionFlags; - private boolean mDumpFull; + private boolean mDumpUnredacted; private final ArrayList<String> mDumpPackages = new ArrayList<>(); private final ArrayList<Integer> mDumpUids = new ArrayList<>(); private final ArrayList<Integer> mDumpUserIds = new ArrayList<>(); private final ArrayList<Long> mDumpBlobIds = new ArrayList<>(); private boolean mDumpHelp; + private boolean mDumpAll; public boolean shouldDumpSession(String packageName, int uid, long blobId) { if (!CollectionUtils.isEmpty(mDumpPackages) @@ -1503,7 +1514,7 @@ public class BlobStoreManagerService extends SystemService { } public boolean shouldDumpAllSections() { - return mSelectedSectionFlags == 0; + return mDumpAll || (mSelectedSectionFlags == 0); } public void allowDumpSessions() { @@ -1545,7 +1556,7 @@ public class BlobStoreManagerService extends SystemService { } public boolean shouldDumpFull() { - return mDumpFull; + return mDumpUnredacted; } public boolean shouldDumpUser(int userId) { @@ -1567,10 +1578,12 @@ public class BlobStoreManagerService extends SystemService { for (int i = 0; i < args.length; ++i) { final String opt = args[i]; - if ("--full".equals(opt) || "-f".equals(opt)) { + if ("--all".equals(opt) || "-a".equals(opt)) { + dumpArgs.mDumpAll = true; + } else if ("--unredacted".equals(opt) || "-u".equals(opt)) { final int callingUid = Binder.getCallingUid(); if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { - dumpArgs.mDumpFull = true; + dumpArgs.mDumpUnredacted = true; } } else if ("--sessions".equals(opt)) { dumpArgs.allowDumpSessions(); @@ -1580,7 +1593,7 @@ public class BlobStoreManagerService extends SystemService { dumpArgs.allowDumpConfig(); } else if ("--package".equals(opt) || "-p".equals(opt)) { dumpArgs.mDumpPackages.add(getStringArgRequired(args, ++i, "packageName")); - } else if ("--uid".equals(opt) || "-u".equals(opt)) { + } else if ("--uid".equals(opt)) { dumpArgs.mDumpUids.add(getIntArgRequired(args, ++i, "uid")); } else if ("--user".equals(opt)) { dumpArgs.mDumpUserIds.add(getIntArgRequired(args, ++i, "userId")); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 573a84f2fe33..c6e9e01cc0d7 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -24,6 +24,7 @@ import "frameworks/base/cmds/statsd/src/atom_field_options.proto"; import "frameworks/base/core/proto/android/app/enums.proto"; import "frameworks/base/core/proto/android/app/job/enums.proto"; import "frameworks/base/core/proto/android/app/settings_enums.proto"; +import "frameworks/base/core/proto/android/app/media_output_enum.proto"; import "frameworks/base/core/proto/android/app/tvsettings_enums.proto"; import "frameworks/base/core/proto/android/bluetooth/a2dp/enums.proto"; import "frameworks/base/core/proto/android/bluetooth/enums.proto"; @@ -441,6 +442,8 @@ message Atom { EvsUsageStatsReported evs_usage_stats_reported = 274 [(module) = "evs"]; AudioPowerUsageDataReported audio_power_usage_data_reported = 275; TvTunerStateChanged tv_tuner_state_changed = 276 [(module) = "framework"]; + MediaOutputOpSwitchReported mediaoutput_op_switch_reported = + 277 [(module) = "settings"]; SdkExtensionStatus sdk_extension_status = 354; // StatsdStats tracks platform atoms with ids upto 500. @@ -9673,6 +9676,9 @@ message UserLifecycleEventOccurred { SWITCH_USER = 1; // Indicates that this is a user switch event START_USER = 2; // Indicates that this is a user start event CREATE_USER = 3; // Indicates that this is a user create event + USER_RUNNING_LOCKED = 4; // Indicates that user is running in locked state + UNLOCKING_USER = 5; // Indicates that this is a user unlocking event + UNLOCKED_USER = 6; // Indicates that this is a user unlocked event } optional Event event = 3; @@ -9864,3 +9870,40 @@ message BytesTransferByTagAndMetered { optional int64 tx_packets = 7; } + +/* + * Logs when the Media Output Switcher finishes a media switch operation. + * + * Logged from: + * packages/apps/Settings/src/com/android/settings/media/MediaOutputSliceWorker.java + */ +message MediaOutputOpSwitchReported { + // Source medium type before switching. + optional android.app.settings.mediaoutput.MediumType source = 1; + + // Target medium type after switching. + optional android.app.settings.mediaoutput.MediumType target = 2; + + // The result of switching. + optional android.app.settings.mediaoutput.SwitchResult result = 3; + + // The detail code of a switching result. + optional android.app.settings.mediaoutput.SubResult subresult = 4; + + /* + * The package name of a pre-installed app, whose media session is being switched. + */ + optional string media_session_package_name = 5; + + // The amount of available wired devices when a switching is being performed. + optional int32 available_wired_device_count = 6; + + // The amount of available Bluetooth devices a switching is being performed. + optional int32 available_bt_device_count = 7; + + // The amount of available remote devices when a switching is being performed. + optional int32 available_remote_device_count = 8; + + // The amount of applied devices within a remote dynamic group after a switching is done. + optional int32 applied_device_count_within_remote_group = 9; +} diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index f1472dd002fd..c491eea7a674 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -428,4 +428,17 @@ public abstract class ActivityManagerInternal { String[] requiredPermissions, boolean serialized, int userId, int[] appIdWhitelist); + /** + * Add or delete uid from the ActivityManagerService PendingStartActivityUids list. + * @param uid uid + * @param pending add to the list if true, delete from list if false. + */ + public abstract void updatePendingTopUid(int uid, boolean pending); + + /** + * Is the uid in ActivityManagerService PendingStartActivityUids list? + * @param uid + * @return true if exists, false otherwise. + */ + public abstract boolean isPendingTopUid(int uid); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index a033b82f48cd..90206b693772 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -7209,7 +7209,8 @@ public class Notification implements Parcelable * * <p>Starting in {@link Build.VERSION_CODES#R, this conversation title will be ignored if a * valid shortcutId is added via {@link Notification.Builder#setShortcutId(String)}. In this - * case, {@link ShortcutInfo#getShortLabel()} will be shown as the conversation title + * case, {@link ShortcutInfo#getLongLabel()} (or, if missing, + * {@link ShortcutInfo#getShortLabel()}) will be shown as the conversation title * instead. * * <p>This API's behavior was changed in SDK version {@link Build.VERSION_CODES#P}. If your diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 8073982ef745..c65064324c8c 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6031,10 +6031,12 @@ public class DevicePolicyManager { * this API to enforce auto time will result in * {@link UserManager#DISALLOW_CONFIG_DATE_TIME} being set, while calling this API to lift * the requirement will result in {@link UserManager#DISALLOW_CONFIG_DATE_TIME} being cleared. + * From Android 11, this API can also no longer be called on a managed profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param required Whether auto time is set required or not. - * @throws SecurityException if {@code admin} is not a device owner. + * @throws SecurityException if {@code admin} is not a device owner, not a profile owner or + * if this API is called on a managed profile. * @deprecated From {@link android.os.Build.VERSION_CODES#R}. Use {@link #setAutoTimeEnabled} * to turn auto time on or off and use {@link UserManager#DISALLOW_CONFIG_DATE_TIME} * to prevent the user from changing this setting. diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java index 41f04f73aa87..8f5dbc45bf1b 100644 --- a/core/java/android/app/admin/DevicePolicyManagerInternal.java +++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java @@ -217,4 +217,9 @@ public abstract class DevicePolicyManagerInternal { */ public abstract void broadcastIntentToCrossProfileManifestReceiversAsUser(Intent intent, UserHandle parentHandle, boolean requiresPermission); + + /** + * Returns the profile owner component for the given user, or {@code null} if there is not one. + */ + public abstract ComponentName getProfileOwnerAsUser(int userHandle); } diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java index d41ace5bcf62..f354bdb5a08b 100644 --- a/core/java/android/content/pm/PackageItemInfo.java +++ b/core/java/android/content/pm/PackageItemInfo.java @@ -24,6 +24,7 @@ import static android.text.TextUtils.makeSafeForPresentation; import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.app.ActivityThread; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -194,7 +195,7 @@ public class PackageItemInfo { * item does not have a label, its name is returned. */ public @NonNull CharSequence loadLabel(@NonNull PackageManager pm) { - if (sForceSafeLabels) { + if (sForceSafeLabels && !Objects.equals(packageName, ActivityThread.currentPackageName())) { return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_STRING_FLAG_TRIM | SAFE_STRING_FLAG_FIRST_LINE); } else { diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 85bf11ceb723..dcc6cb25c95b 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -1450,6 +1450,21 @@ public final class ShortcutInfo implements Parcelable { return mText; } + /** + * Returns the {@link #getLongLabel()} if it's populated, and if not, the + * {@link #getShortLabel()}. + * @hide + */ + @Nullable + public CharSequence getLabel() { + CharSequence label = getLongLabel(); + if (TextUtils.isEmpty(label)) { + label = getShortLabel(); + } + + return label; + } + /** @hide */ public int getLongLabelResourceId() { return mTextResId; diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 230aa044a9db..6bbc37a90fae 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -34,6 +34,7 @@ import android.hardware.camera2.legacy.LegacyMetadataMapper; import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.utils.CameraIdAndSessionConfiguration; import android.hardware.camera2.utils.ConcurrentCameraIdCombination; +import android.hardware.display.DisplayManager; import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; @@ -47,7 +48,6 @@ import android.util.ArraySet; import android.util.Log; import android.util.Size; import android.view.Display; -import android.view.WindowManager; import java.util.ArrayList; import java.util.Arrays; @@ -138,10 +138,25 @@ public final class CameraManager { * client camera application. Using these camera devices concurrently by two different * applications is not guaranteed to be supported, however.</p> * + * <p>For concurrent operation, in chronological order : + * - Applications must first close any open cameras that have sessions configured, using + * {@link CameraDevice#close}. + * - All camera devices intended to be operated concurrently, must be opened using + * {@link #openCamera}, before configuring sessions on any of the camera devices.</p> + * * <p>Each device in a combination, is guaranteed to support stream combinations which may be * obtained by querying {@link #getCameraCharacteristics} for the key * {@link android.hardware.camera2.CameraCharacteristics#SCALER_MANDATORY_CONCURRENT_STREAM_COMBINATIONS}.</p> * + * <p>For concurrent operation, if a camera device has a non null zoom ratio range as specified + * by + * {@link android.hardware.camera2.CameraCharacteristics#CONTROL_ZOOM_RATIO_RANGE}, + * its complete zoom ratio range may not apply. Applications can use + * {@link android.hardware.camera2.CaptureRequest#CONTROL_ZOOM_RATIO} >=1 and <= + * {@link android.hardware.camera2.CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM} + * during concurrent operation. + * <p> + * * <p>The set of combinations may include camera devices that may be in use by other camera API * clients.</p> * @@ -334,19 +349,22 @@ public final class CameraManager { Size ret = new Size(0, 0); try { - WindowManager windowManager = - (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); - Display display = windowManager.getDefaultDisplay(); - - int width = display.getWidth(); - int height = display.getHeight(); + DisplayManager displayManager = + (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); + Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + if (display != null) { + int width = display.getWidth(); + int height = display.getHeight(); + + if (height > width) { + height = width; + width = display.getHeight(); + } - if (height > width) { - height = width; - width = display.getHeight(); + ret = new Size(width, height); + } else { + Log.e(TAG, "Invalid default display!"); } - - ret = new Size(width, height); } catch (Exception e) { Log.e(TAG, "getDisplaySize Failed. " + e.toString()); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 4832e564dbcf..ebf4cc5c938e 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -478,8 +478,8 @@ public class UserManager { public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials"; /** - * When set on the primary user this specifies if the user can remove other users. - * When set on a secondary user, this specifies if the user can remove itself. + * When set on the admin user this specifies if the user can remove users. + * When set on a non-admin secondary user, this specifies if the user can remove itself. * This restriction has no effect on managed profiles. * The default value is <code>false</code>. * @@ -619,11 +619,11 @@ public class UserManager { public static final String DISALLOW_NETWORK_RESET = "no_network_reset"; /** - * Specifies if a user is disallowed from factory resetting - * from Settings. This can only be set by device owners and profile owners on the primary user. + * Specifies if a user is disallowed from factory resetting from Settings. + * This can only be set by device owners and profile owners on an admin user. * The default value is <code>false</code>. - * <p>This restriction has no effect on secondary users and managed profiles since only the - * primary user can factory reset the device. + * <p>This restriction has no effect on non-admin users since they cannot factory reset the + * device. * * <p>Key for user restrictions. * <p>Type: Boolean diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 3dc8e9924444..bf3d46fa4a44 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -333,7 +333,7 @@ public final class PermissionManager { /** * Gets the list of packages that have permissions that specified - * {@code allowDontAutoRevokePermissions=true} in their + * {@code autoRevokePermissions=disallowed} in their * {@code application} manifest declaration. * * @return the list of packages for current user diff --git a/core/java/android/util/AtomicFile.java b/core/java/android/util/AtomicFile.java index 1dd4cbb403db..e0d857af597c 100644 --- a/core/java/android/util/AtomicFile.java +++ b/core/java/android/util/AtomicFile.java @@ -116,10 +116,7 @@ public class AtomicFile { mStartTime = startTime; if (mLegacyBackupName.exists()) { - if (!mLegacyBackupName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName - + " to base file " + mBaseName); - } + rename(mLegacyBackupName, mBaseName); } try { @@ -157,9 +154,7 @@ public class AtomicFile { } catch (IOException e) { Log.e(LOG_TAG, "Failed to close file output stream", e); } - if (!mNewName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename new file " + mNewName + " to base file " + mBaseName); - } + rename(mNewName, mBaseName); if (mCommitTag != null) { com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( mCommitTag, SystemClock.uptimeMillis() - mStartTime); @@ -221,14 +216,21 @@ public class AtomicFile { */ public FileInputStream openRead() throws FileNotFoundException { if (mLegacyBackupName.exists()) { - if (!mLegacyBackupName.renameTo(mBaseName)) { - Log.e(LOG_TAG, "Failed to rename legacy backup file " + mLegacyBackupName - + " to base file " + mBaseName); - } + rename(mLegacyBackupName, mBaseName); } - // Don't delete mNewName here - it was okay to call openRead() between startWrite() and - // finishWrite(), and we have to keep supporting it. + // It was okay to call openRead() between startWrite() and finishWrite() for the first time + // (because there is no backup file), where openRead() would open the file being written, + // which makes no sense, but finishWrite() would still persist the write properly. For all + // subsequent writes, if openRead() was called in between, it would see a backup file and + // delete the file being written, the same behavior as our new implementation. So we only + // need a special case for the first write, and don't delete the new file in this case so + // that finishWrite() can still work. + if (mNewName.exists() && mBaseName.exists()) { + if (!mNewName.delete()) { + Log.e(LOG_TAG, "Failed to delete outdated new file " + mNewName); + } + } return new FileInputStream(mBaseName); } @@ -301,4 +303,21 @@ public class AtomicFile { IoUtils.closeQuietly(out); } } + + private static void rename(File source, File target) { + // We used to delete the target file before rename, but that isn't atomic, and the rename() + // syscall should atomically replace the target file. However in the case where the target + // file is a directory, a simple rename() won't work. We need to delete the file in this + // case because there are callers who erroneously called mBaseName.mkdirs() (instead of + // mBaseName.getParentFile().mkdirs()) before creating the AtomicFile, and it worked + // regardless, so this deletion became some kind of API. + if (target.isDirectory()) { + if (!target.delete()) { + Log.e(LOG_TAG, "Failed to delete file which is a directory " + target); + } + } + if (!source.renameTo(target)) { + Log.e(LOG_TAG, "Failed to rename " + source + " to " + target); + } + } } diff --git a/core/java/android/view/IDisplayWindowListener.aidl b/core/java/android/view/IDisplayWindowListener.aidl index 973a208bf485..610e0f866b43 100644 --- a/core/java/android/view/IDisplayWindowListener.aidl +++ b/core/java/android/view/IDisplayWindowListener.aidl @@ -46,4 +46,13 @@ oneway interface IDisplayWindowListener { */ void onDisplayRemoved(int displayId); + /** + * Called when fixed rotation is started on a display. + */ + void onFixedRotationStarted(int displayId, int newRotation); + + /** + * Called when the previous fixed rotation on a display is finished. + */ + void onFixedRotationFinished(int displayId); } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 9950e55f1415..389e33ae7ae2 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -99,7 +99,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.MeasureSpec; import android.view.View.OnClickListener; -import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.animation.AccelerateInterpolator; @@ -1622,32 +1621,22 @@ public class ChooserActivity extends ResolverActivity implements return getIntent().getBooleanExtra(Intent.EXTRA_AUTO_LAUNCH_SINGLE_CHOICE, true); } - void showTargetDetails(TargetInfo ti) { - if (ti == null) { - return; - } - ComponentName name = ti.getResolveInfo().activityInfo.getComponentName(); - boolean pinned = mPinnedSharedPrefs.getBoolean(name.flattenToString(), false); + private void showTargetDetails(DisplayResolveInfo ti) { + if (ti == null) return; - ResolverTargetActionsDialogFragment f; + List<DisplayResolveInfo> targetList; // For multiple targets, include info on all targets if (ti instanceof MultiDisplayResolveInfo) { MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) ti; - List<CharSequence> labels = new ArrayList<>(); - - for (TargetInfo innerInfo : mti.getTargets()) { - labels.add(innerInfo.getResolveInfo().loadLabel(getPackageManager())); - } - f = new ResolverTargetActionsDialogFragment(mti.getDisplayLabel(), name, - mti.getTargets(), labels, - mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + targetList = mti.getTargets(); } else { - f = new ResolverTargetActionsDialogFragment( - ti.getResolveInfo().loadLabel(getPackageManager()), name, pinned, - mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + targetList = Collections.singletonList(ti); } + ResolverTargetActionsDialogFragment f = new ResolverTargetActionsDialogFragment( + targetList, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); + f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); } @@ -2156,7 +2145,10 @@ public class ChooserActivity extends ResolverActivity implements Bundle extras = new Bundle(); extras.putString(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId()); - ChooserTarget chooserTarget = new ChooserTarget(shortcutInfo.getShortLabel(), + + ChooserTarget chooserTarget = new ChooserTarget( + shortcutInfo.getLongLabel() != null ? shortcutInfo.getLongLabel() + : shortcutInfo.getShortLabel(), null, // Icon will be loaded later if this target is selected to be shown. score, matchingShortcuts.get(i).getTargetComponent().clone(), extras); @@ -2979,12 +2971,17 @@ public class ChooserActivity extends ResolverActivity implements if (isClickable) { itemView.setOnClickListener(v -> startSelected(mListPosition, false/* always */, true/* filterd */)); - itemView.setOnLongClickListener(v -> { - showTargetDetails( - mChooserMultiProfilePagerAdapter.getActiveListAdapter() - .targetInfoForPosition(mListPosition, /* filtered */ true)); - return true; - }); + + TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() + .targetInfoForPosition(mListPosition, /* filtered */ true); + + // This should always be the case for ItemViewHolder, check for sanity + if (ti instanceof DisplayResolveInfo) { + itemView.setOnLongClickListener(v -> { + showTargetDetails((DisplayResolveInfo) ti); + return true; + }); + } } } } @@ -3309,15 +3306,21 @@ public class ChooserActivity extends ResolverActivity implements startSelected(holder.getItemIndex(column), false, true); } }); - v.setOnLongClickListener(new OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - showTargetDetails( - mChooserListAdapter.targetInfoForPosition( - holder.getItemIndex(column), true)); - return true; + + // Direct Share targets should not show any menu + if (!isDirectShare) { + final TargetInfo ti = mChooserListAdapter.targetInfoForPosition( + holder.getItemIndex(column), true); + + // This should always be the case for non-DS targets, check for sanity + if (ti instanceof DisplayResolveInfo) { + v.setOnLongClickListener(v1 -> { + showTargetDetails((DisplayResolveInfo) ti); + return true; + }); } - }); + } + holder.addView(i, v); // Force Direct Share to be 2 lines and auto-wrap to second line via hoz scroll = diff --git a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java index 35d9bcdbb033..cdc600c51451 100644 --- a/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java +++ b/core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java @@ -17,21 +17,25 @@ package com.android.internal.app; +import static android.content.Context.ACTIVITY_SERVICE; + +import static com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; + +import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.ComponentName; import android.content.DialogInterface; -import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; -import android.provider.Settings; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; +import com.android.internal.app.chooser.TargetInfo; import java.util.ArrayList; import java.util.List; @@ -41,94 +45,53 @@ import java.util.List; */ public class ResolverTargetActionsDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { - private static final String NAME_KEY = "componentName"; - private static final String TITLE_KEY = "title"; - private static final String PINNED_KEY = "pinned"; - private static final String USER_ID_KEY = "userId"; - - // Sync with R.array.resolver_target_actions_* resources - private static final int TOGGLE_PIN_INDEX = 0; - private static final int APP_INFO_INDEX = 1; private List<DisplayResolveInfo> mTargetInfos = new ArrayList<>(); - private List<CharSequence> mLabels = new ArrayList<>(); - private boolean[] mPinned; + private UserHandle mUserHandle; public ResolverTargetActionsDialogFragment() { } - public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name, - boolean pinned, UserHandle userHandle) { - Bundle args = new Bundle(); - args.putCharSequence(TITLE_KEY, title); - args.putParcelable(NAME_KEY, name); - args.putBoolean(PINNED_KEY, pinned); - args.putParcelable(USER_ID_KEY, userHandle); - setArguments(args); - } - - public ResolverTargetActionsDialogFragment(CharSequence title, ComponentName name, - List<DisplayResolveInfo> targets, List<CharSequence> labels, UserHandle userHandle) { - Bundle args = new Bundle(); - args.putCharSequence(TITLE_KEY, title); - args.putParcelable(NAME_KEY, name); - args.putParcelable(USER_ID_KEY, userHandle); + public ResolverTargetActionsDialogFragment(List<DisplayResolveInfo> targets, + UserHandle userHandle) { + mUserHandle = userHandle; mTargetInfos = targets; - mLabels = labels; - setArguments(args); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); - final int itemRes = args.getBoolean(PINNED_KEY, false) - ? R.array.resolver_target_actions_unpin - : R.array.resolver_target_actions_pin; - String[] defaultActions = getResources().getStringArray(itemRes); - CharSequence[] items; - - if (mTargetInfos == null || mTargetInfos.size() < 2) { - items = defaultActions; - } else { - // Pin item for each sub-item - items = new CharSequence[mTargetInfos.size() + 1]; - for (int i = 0; i < mTargetInfos.size(); i++) { - items[i] = mTargetInfos.get(i).isPinned() - ? getResources().getString(R.string.unpin_specific_target, mLabels.get(i)) - : getResources().getString(R.string.pin_specific_target, mLabels.get(i)); - } - // "App info" - items[mTargetInfos.size()] = defaultActions[1]; + final PackageManager pm = getContext().getPackageManager(); + + // Pin item for each sub-item + CharSequence[] items = new CharSequence[mTargetInfos.size()]; + for (int i = 0; i < mTargetInfos.size(); i++) { + final TargetInfo ti = mTargetInfos.get(i); + final CharSequence label = ti.getResolveInfo().loadLabel(pm); + items[i] = ti.isPinned() + ? getResources().getString(R.string.unpin_specific_target, label) + : getResources().getString(R.string.pin_specific_target, label); } + // Use the matching application icon and label for the title, any TargetInfo will do + final ActivityManager am = (ActivityManager) getContext() + .getSystemService(ACTIVITY_SERVICE); + final int iconDpi = am.getLauncherLargeIconDensity(); + final ResolveInfoPresentationGetter pg = new ResolveInfoPresentationGetter(getContext(), + iconDpi, mTargetInfos.get(0).getResolveInfo()); return new Builder(getContext()) + .setTitle(pg.getLabel()) + .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setItems(items, this) - .setTitle(args.getCharSequence(TITLE_KEY)) .create(); } @Override public void onClick(DialogInterface dialog, int which) { - final Bundle args = getArguments(); - ComponentName name = args.getParcelable(NAME_KEY); - if (which == 0 || (mTargetInfos.size() > 0 && which < mTargetInfos.size())) { - if (mTargetInfos == null || mTargetInfos.size() == 0) { - pinComponent(name); - } else { - pinComponent(mTargetInfos.get(which).getResolvedComponentName()); - } - // Force the chooser to requery and resort things - ((ChooserActivity) getActivity()).handlePackagesChanged(); - } else { - // Last item in dialog is App Info - Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - .setData(Uri.fromParts("package", name.getPackageName(), null)) - .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); - UserHandle userHandle = args.getParcelable(USER_ID_KEY); - getActivity().startActivityAsUser(in, userHandle); - } + pinComponent(mTargetInfos.get(which).getResolvedComponentName()); + ((ChooserActivity) getActivity()).handlePackagesChanged(); dismiss(); } diff --git a/core/jni/android_os_storage_StorageManager.cpp b/core/jni/android_os_storage_StorageManager.cpp index fd3e66b1bbce..3116cc8f19e6 100644 --- a/core/jni/android_os_storage_StorageManager.cpp +++ b/core/jni/android_os_storage_StorageManager.cpp @@ -17,33 +17,23 @@ #define LOG_TAG "StorageManager" #include <android-base/file.h> #include <android-base/logging.h> +#include <android-base/properties.h> #include <android-base/unique_fd.h> #include <fcntl.h> #include <linux/fs.h> #include <nativehelper/JNIHelp.h> #include "core_jni_helpers.h" +#include "filesystem_utils.h" namespace android { -static const char* kProcFilesystems = "/proc/filesystems"; - -// Checks whether the passed in filesystem is listed in /proc/filesystems -static bool IsFilesystemSupported(const std::string& fsType) { - std::string supported; - if (!android::base::ReadFileToString(kProcFilesystems, &supported)) { - PLOG(ERROR) << "Failed to read supported filesystems"; - return false; - } - return supported.find(fsType + "\n") != std::string::npos; -} - jboolean android_os_storage_StorageManager_setQuotaProjectId(JNIEnv* env, jobject self, jstring path, jlong projectId) { struct fsxattr fsx; ScopedUtfChars utf_chars_path(env, path); - static bool sdcardFsSupported = IsFilesystemSupported("sdcardfs"); + static bool sdcardFsSupported = IsSdcardfsUsed(); if (sdcardFsSupported) { // sdcardfs doesn't support project ID quota tracking and takes care of quota // in a different way. diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index c5bc083dfabf..fc2005a31696 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -88,12 +88,13 @@ #include <utils/String8.h> #include <utils/Trace.h> -#include "core_jni_helpers.h" #include <nativehelper/JNIHelp.h> #include <nativehelper/ScopedLocalRef.h> #include <nativehelper/ScopedPrimitiveArray.h> #include <nativehelper/ScopedUtfChars.h> +#include "core_jni_helpers.h" #include "fd_utils.h" +#include "filesystem_utils.h" #include "nativebridge/native_bridge.h" @@ -614,15 +615,6 @@ static void EnableDebugger() { } } -static bool IsFilesystemSupported(const std::string& fsType) { - std::string supported; - if (!ReadFileToString("/proc/filesystems", &supported)) { - ALOGE("Failed to read supported filesystems"); - return false; - } - return supported.find(fsType + "\n") != std::string::npos; -} - static void PreApplicationInit() { // The child process sets this to indicate it's not the zygote. android_mallopt(M_SET_ZYGOTE_CHILD, nullptr, 0); @@ -1554,15 +1546,14 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, static void BindMountStorageToLowerFs(const userid_t user_id, const uid_t uid, const char* dir_name, const char* package, fail_fn_t fail_fn) { - - bool hasSdcardFs = IsFilesystemSupported("sdcardfs"); - std::string source; - if (hasSdcardFs) { - source = StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package); - } else { - source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", - user_id, user_id, dir_name, package); - } + bool hasSdcardFs = IsSdcardfsUsed(); + std::string source; + if (hasSdcardFs) { + source = StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package); + } else { + source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s", user_id, user_id, dir_name, + package); + } std::string target = StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package); // As the parent is mounted as tmpfs, we need to create the target dir here. diff --git a/core/jni/filesystem_utils.h b/core/jni/filesystem_utils.h new file mode 100644 index 000000000000..c4728a09883b --- /dev/null +++ b/core/jni/filesystem_utils.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAMEWORKS_BASE_CORE_JNI_MISC_UTILS_H_ +#define FRAMEWORKS_BASE_CORE_JNI_MISC_UTILS_H_ + +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/properties.h> +#include <fcntl.h> +#include <linux/fs.h> + +namespace { +static constexpr const char* kExternalStorageSdcardfs = "external_storage.sdcardfs.enabled"; + +static bool IsFilesystemSupported(const std::string& fsType) { + std::string supported; + if (!android::base::ReadFileToString("/proc/filesystems", &supported)) { + ALOGE("Failed to read supported filesystems"); + return false; + } + return supported.find(fsType + "\n") != std::string::npos; +} + +static inline bool IsSdcardfsUsed() { + return IsFilesystemSupported("sdcardfs") && + android::base::GetBoolProperty(kExternalStorageSdcardfs, true); +} +} // namespace +#endif // FRAMEWORKS_BASE_CORE_JNI_MISC_UTILS_H_ diff --git a/core/proto/android/app/media_output_enum.proto b/core/proto/android/app/media_output_enum.proto new file mode 100644 index 000000000000..0d42fb77025a --- /dev/null +++ b/core/proto/android/app/media_output_enum.proto @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; + +package android.app.settings.mediaoutput; +option java_multiple_files = true; + +/** + * The medium type specified in an output switching operation. + */ +enum MediumType { + UNKNOWN_TYPE = 0; + BUILTIN_SPEAKER = 1; + WIRED_3POINT5_MM_AUDIO = 100; + WIRED_3POINT5_MM_HEADSET = 101; + WIRED_3POINT5_MM_HEADPHONES = 102; + USB_C_AUDIO = 200; + USB_C_DEVICE = 201; + USB_C_HEADSET = 202; + USB_C_ACCESSORY = 203; + USB_C_DOCK = 204; + USB_C_HDMI = 205; + BLUETOOTH = 300; + BLUETOOTH_HEARING_AID = 301; + BLUETOOTH_A2DP = 302; + REMOTE_SINGLE = 400; + REMOTE_TV = 401; + REMOTE_SPEAKER = 402; + REMOTE_GROUP = 500; + REMOTE_DYNAMIC_GROUP = 501; +}; + +/** + * The result of an output switching operation. + */ +enum SwitchResult { + ERROR = 0; + OK = 1; +}; + +/** + * The sub result of an output switching operation. + */ +enum SubResult { + UNKNOWN_ERROR = 0; + NO_ERROR = 1; + REJECTED = 2; + NETWORK_ERROR = 3; + ROUTE_NOT_AVAILABLE = 4; + INVALID_COMMAND = 5; +} diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto index bfa5d70663ab..997829eacf96 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2678,15 +2678,4 @@ enum PageId { // CATEGORY: SETTINGS // OS: R DEVICE_CONTROLS_SETTINGS = 1844; - - // ACTION: Settings > Wi-Fi > Tap on Openroaming Wi-Fi - // CATEGORY: SETTINGS - // OS: R - OPENROAMING_TAP = 1845; - - // When device already using any Wi-Fi service, to track if user still want to use Openroaming - // ACTION: Settings > Wi-Fi > Tap on Openroaming Wi-Fi - // CATEGORY: SETTINGS - // OS: R - OPENROAMING_TAP_ON_WIFI_CONNECTION = 1846; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index d4cc636ec60b..f285d9504822 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2437,7 +2437,7 @@ <!-- Allows interaction across profiles in the same profile group. --> <permission android:name="android.permission.INTERACT_ACROSS_PROFILES" - android:protectionLevel="signature|appop|documenter|wellbeing" /> + android:protectionLevel="signature|appop" /> <!-- Allows configuring apps to have the INTERACT_ACROSS_PROFILES permission so that they can interact across profiles in the same profile group. diff --git a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java index 70e342370545..a4656403b03f 100644 --- a/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java +++ b/core/tests/overlaytests/remount/src/com/android/overlaytest/remounted/PackagedUpgradedTest.java @@ -47,6 +47,7 @@ public class PackagedUpgradedTest extends OverlayRemountedTestBase { @Test public void testTargetRelocated() throws Exception { final String targetOverlaid = resourceName(TARGET_PACKAGE, "bool", "target_overlaid"); + final String targetReference = resourceName(TARGET_PACKAGE, "bool", "target_reference"); final String originalPath = "/product/app/OverlayTarget.apk"; mPreparer.pushResourceFile(TARGET_APK, originalPath) @@ -54,6 +55,7 @@ public class PackagedUpgradedTest extends OverlayRemountedTestBase { .installResourceApk(OVERLAY_APK, OVERLAY_PACKAGE) .setOverlayEnabled(OVERLAY_PACKAGE, true); + assertResource(targetReference, "@" + 0x7f010000 + " -> true"); assertResource(targetOverlaid, "true"); mPreparer.remount(); @@ -61,6 +63,7 @@ public class PackagedUpgradedTest extends OverlayRemountedTestBase { mPreparer.pushResourceFile(TARGET_UPGRADE_APK, "/product/app/OverlayTarget2.apk") .reboot(); + assertResource(targetReference, "@" + 0x7f0100ff + " -> true"); assertResource(targetOverlaid, "true"); } } diff --git a/core/tests/utiltests/src/android/util/AtomicFileTest.java b/core/tests/utiltests/src/android/util/AtomicFileTest.java index 547d4d844181..a7d3b222937a 100644 --- a/core/tests/utiltests/src/android/util/AtomicFileTest.java +++ b/core/tests/utiltests/src/android/util/AtomicFileTest.java @@ -17,6 +17,7 @@ package android.util; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertTrue; import android.app.Instrumentation; import android.content.Context; @@ -45,11 +46,14 @@ public class AtomicFileTest { private static final String BASE_NAME = "base"; private static final String NEW_NAME = BASE_NAME + ".new"; private static final String LEGACY_BACKUP_NAME = BASE_NAME + ".bak"; + // The string isn't actually used, but we just need a different identifier. + private static final String BASE_NAME_DIRECTORY = BASE_NAME + ".dir"; private enum WriteAction { FINISH, FAIL, - ABORT + ABORT, + READ_FINISH } private static final byte[] BASE_BYTES = "base".getBytes(StandardCharsets.UTF_8); @@ -82,6 +86,7 @@ public class AtomicFileTest { @Parameterized.Parameters(name = "{0}") public static Object[][] data() { return new Object[][] { + // Standard tests. { "none + none = none", null, null, null }, { "none + finish = new", null, WriteAction.FINISH, NEW_BYTES }, { "none + fail = none", null, WriteAction.FAIL, null }, @@ -140,6 +145,50 @@ public class AtomicFileTest { { "base & new & bak + abort = bak", new String[] { BASE_NAME, NEW_NAME, LEGACY_BACKUP_NAME }, WriteAction.ABORT, LEGACY_BACKUP_BYTES }, + // Compatibility when there is a directory in the place of base file, by replacing + // no base with base.dir. + { "base.dir + none = none", new String[] { BASE_NAME_DIRECTORY }, null, null }, + { "base.dir + finish = new", new String[] { BASE_NAME_DIRECTORY }, + WriteAction.FINISH, NEW_BYTES }, + { "base.dir + fail = none", new String[] { BASE_NAME_DIRECTORY }, WriteAction.FAIL, + null }, + { "base.dir + abort = none", new String[] { BASE_NAME_DIRECTORY }, + WriteAction.ABORT, null }, + { "base.dir & new + none = none", new String[] { BASE_NAME_DIRECTORY, NEW_NAME }, + null, null }, + { "base.dir & new + finish = new", new String[] { BASE_NAME_DIRECTORY, NEW_NAME }, + WriteAction.FINISH, NEW_BYTES }, + { "base.dir & new + fail = none", new String[] { BASE_NAME_DIRECTORY, NEW_NAME }, + WriteAction.FAIL, null }, + { "base.dir & new + abort = none", new String[] { BASE_NAME_DIRECTORY, NEW_NAME }, + WriteAction.ABORT, null }, + { "base.dir & bak + none = bak", + new String[] { BASE_NAME_DIRECTORY, LEGACY_BACKUP_NAME }, null, + LEGACY_BACKUP_BYTES }, + { "base.dir & bak + finish = new", + new String[] { BASE_NAME_DIRECTORY, LEGACY_BACKUP_NAME }, + WriteAction.FINISH, NEW_BYTES }, + { "base.dir & bak + fail = bak", + new String[] { BASE_NAME_DIRECTORY, LEGACY_BACKUP_NAME }, WriteAction.FAIL, + LEGACY_BACKUP_BYTES }, + { "base.dir & bak + abort = bak", + new String[] { BASE_NAME_DIRECTORY, LEGACY_BACKUP_NAME }, WriteAction.ABORT, + LEGACY_BACKUP_BYTES }, + { "base.dir & new & bak + none = bak", + new String[] { BASE_NAME_DIRECTORY, NEW_NAME, LEGACY_BACKUP_NAME }, null, + LEGACY_BACKUP_BYTES }, + { "base.dir & new & bak + finish = new", + new String[] { BASE_NAME_DIRECTORY, NEW_NAME, LEGACY_BACKUP_NAME }, + WriteAction.FINISH, NEW_BYTES }, + { "base.dir & new & bak + fail = bak", + new String[] { BASE_NAME_DIRECTORY, NEW_NAME, LEGACY_BACKUP_NAME }, + WriteAction.FAIL, LEGACY_BACKUP_BYTES }, + { "base.dir & new & bak + abort = bak", + new String[] { BASE_NAME_DIRECTORY, NEW_NAME, LEGACY_BACKUP_NAME }, + WriteAction.ABORT, LEGACY_BACKUP_BYTES }, + // Compatibility when openRead() is called between startWrite() and finishWrite() - + // the write should still succeed if it's the first write. + { "none + read & finish = new", null, WriteAction.READ_FINISH, NEW_BYTES }, }; } @@ -165,6 +214,9 @@ public class AtomicFileTest { case LEGACY_BACKUP_NAME: writeBytes(mLegacyBackupFile, LEGACY_BACKUP_BYTES); break; + case BASE_NAME_DIRECTORY: + assertTrue(mBaseFile.mkdir()); + break; default: throw new AssertionError(fileName); } @@ -185,6 +237,11 @@ public class AtomicFileTest { case ABORT: // Neither finishing nor failing is called upon abort. break; + case READ_FINISH: + // We are only using this action when there is no base file. + assertThrows(FileNotFoundException.class, atomicFile::openRead); + atomicFile.finishWrite(outputStream); + break; default: throw new AssertionError(mWriteAction); } @@ -196,7 +253,7 @@ public class AtomicFileTest { assertArrayEquals(mExpectedBytes, readAllBytes(inputStream)); } } else { - assertThrows(FileNotFoundException.class, () -> atomicFile.openRead()); + assertThrows(FileNotFoundException.class, atomicFile::openRead); } } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java index 8dbb5f544ad4..cc5286d70cab 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java @@ -167,7 +167,7 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { boolean userAuthenticationRequired = !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED); long userAuthenticationValidityDurationSeconds = - keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, -1); + keyCharacteristics.getUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT, 0); if (userAuthenticationValidityDurationSeconds > Integer.MAX_VALUE) { throw new ProviderException("User authentication timeout validity too long: " + userAuthenticationValidityDurationSeconds + " seconds"); diff --git a/media/java/android/media/tv/tuner/dvr/DvrSettings.java b/media/java/android/media/tv/tuner/dvr/DvrSettings.java index 3df721cdf18b..60f0d1686ea7 100644 --- a/media/java/android/media/tv/tuner/dvr/DvrSettings.java +++ b/media/java/android/media/tv/tuner/dvr/DvrSettings.java @@ -139,6 +139,10 @@ public class DvrSettings { /** * Sets status mask. + * + * <p>Use Filter.STATUS_ for {@link DvrRecorder} and DvrPlayback.STATUS_ for + * {@link DvrPlayback}. + * <p>If status mask is not set, no status is send to the listener. */ @NonNull public Builder setStatusMask(@Filter.Status int statusMask) { diff --git a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java index 561e4da59bf5..f54b686304c1 100644 --- a/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java +++ b/media/java/android/media/tv/tuner/filter/IpFilterConfiguration.java @@ -100,7 +100,7 @@ public final class IpFilterConfiguration extends FilterConfiguration { */ public static final class Builder { private byte[] mSrcIpAddress = {0, 0, 0, 0}; - private byte[] mDstIpAddress = {0, 0, 0, 0};; + private byte[] mDstIpAddress = {0, 0, 0, 0}; private int mSrcPort = 0; private int mDstPort = 0; private boolean mPassthrough = false; diff --git a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java index 3a45a18855a6..2aa40f9d45f7 100644 --- a/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java +++ b/media/java/android/media/tv/tuner/filter/MmtpFilterConfiguration.java @@ -50,7 +50,7 @@ public final class MmtpFilterConfiguration extends FilterConfiguration { } /** - * Creates a builder for {@link IpFilterConfiguration}. + * Creates a builder for {@link MmtpFilterConfiguration}. */ @NonNull public static Builder builder() { @@ -58,7 +58,7 @@ public final class MmtpFilterConfiguration extends FilterConfiguration { } /** - * Builder for {@link IpFilterConfiguration}. + * Builder for {@link MmtpFilterConfiguration}. */ public static final class Builder { private int mMmtpPid = Tuner.INVALID_TS_PID; diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 805831442756..fb8c276ecc8d 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -2362,28 +2362,25 @@ static sp<Filter> getFilter(JNIEnv *env, jobject filter) { return (Filter *)env->GetLongField(filter, gFields.filterContext); } -static DvrSettings getDvrSettings(JNIEnv *env, jobject settings) { +static DvrSettings getDvrSettings(JNIEnv *env, jobject settings, bool isRecorder) { DvrSettings dvrSettings; jclass clazz = env->FindClass("android/media/tv/tuner/dvr/DvrSettings"); uint32_t statusMask = static_cast<uint32_t>(env->GetIntField( settings, env->GetFieldID(clazz, "mStatusMask", "I"))); uint32_t lowThreshold = - static_cast<uint32_t>(env->GetIntField( - settings, env->GetFieldID(clazz, "mLowThreshold", "I"))); + static_cast<uint32_t>(env->GetLongField( + settings, env->GetFieldID(clazz, "mLowThreshold", "J"))); uint32_t highThreshold = - static_cast<uint32_t>(env->GetIntField( - settings, env->GetFieldID(clazz, "mHighThreshold", "I"))); + static_cast<uint32_t>(env->GetLongField( + settings, env->GetFieldID(clazz, "mHighThreshold", "J"))); uint8_t packetSize = - static_cast<uint8_t>(env->GetIntField( - settings, env->GetFieldID(clazz, "mPacketSize", "I"))); + static_cast<uint8_t>(env->GetLongField( + settings, env->GetFieldID(clazz, "mPacketSize", "J"))); DataFormat dataFormat = static_cast<DataFormat>(env->GetIntField( settings, env->GetFieldID(clazz, "mDataFormat", "I"))); - DvrType type = - static_cast<DvrType>(env->GetIntField( - settings, env->GetFieldID(clazz, "mType", "I"))); - if (type == DvrType::RECORD) { + if (isRecorder) { RecordSettings recordSettings { .statusMask = static_cast<unsigned char>(statusMask), .lowThreshold = lowThreshold, @@ -2392,7 +2389,7 @@ static DvrSettings getDvrSettings(JNIEnv *env, jobject settings) { .packetSize = packetSize, }; dvrSettings.record(recordSettings); - } else if (type == DvrType::PLAYBACK) { + } else { PlaybackSettings PlaybackSettings { .statusMask = statusMask, .lowThreshold = lowThreshold, @@ -3101,8 +3098,9 @@ static jint android_media_tv_Tuner_read_filter_fmq( JNIEnv *env, jobject filter, jbyteArray buffer, jlong offset, jlong size) { sp<Filter> filterSp = getFilter(env, filter); if (filterSp == NULL) { - ALOGD("Failed to read filter FMQ: filter not found"); - return (jint) Result::INVALID_STATE; + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to read filter FMQ: filter not found"); + return 0; } return copyData(env, filterSp->mFilterMQ, filterSp->mFilterMQEventFlag, buffer, offset, size); } @@ -3337,7 +3335,9 @@ static jint android_media_tv_Tuner_configure_dvr(JNIEnv *env, jobject dvr, jobje return (int)Result::NOT_INITIALIZED; } sp<IDvr> iDvrSp = dvrSp->getIDvr(); - Result result = iDvrSp->configure(getDvrSettings(env, settings)); + bool isRecorder = + env->IsInstanceOf(dvr, env->FindClass("android/media/tv/tuner/dvr/DvrRecorder")); + Result result = iDvrSp->configure(getDvrSettings(env, settings, isRecorder)); if (result != Result::SUCCESS) { return (jint) result; } @@ -3440,19 +3440,21 @@ static int android_media_tv_Tuner_close_lnb(JNIEnv* env, jobject lnb) { return (jint) r; } -static void android_media_tv_Tuner_dvr_set_fd(JNIEnv *env, jobject dvr, jobject jfd) { +static void android_media_tv_Tuner_dvr_set_fd(JNIEnv *env, jobject dvr, jint fd) { sp<Dvr> dvrSp = getDvr(env, dvr); if (dvrSp == NULL) { ALOGD("Failed to set FD for dvr: dvr not found"); } - dvrSp->mFd = jniGetFDFromFileDescriptor(env, jfd); + dvrSp->mFd = (int) fd; ALOGD("set fd = %d", dvrSp->mFd); } static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong size) { sp<Dvr> dvrSp = getDvr(env, dvr); if (dvrSp == NULL) { - ALOGD("Failed to read dvr: dvr not found"); + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to read dvr: dvr not found"); + return 0; } long available = dvrSp->mDvrMQ->availableToWrite(); @@ -3466,6 +3468,12 @@ static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong siz long length = first.getLength(); long firstToWrite = std::min(length, write); ret = read(dvrSp->mFd, data, firstToWrite); + + if (ret < 0) { + ALOGE("[DVR] Failed to read from FD: %s", strerror(errno)); + jniThrowRuntimeException(env, strerror(errno)); + return 0; + } if (ret < firstToWrite) { ALOGW("[DVR] file to MQ, first region: %ld bytes to write, but %ld bytes written", firstToWrite, ret); @@ -3480,6 +3488,7 @@ static jlong android_media_tv_Tuner_read_dvr(JNIEnv *env, jobject dvr, jlong siz ALOGD("[DVR] file to MQ: %ld bytes need to be written, %ld bytes written", write, ret); if (!dvrSp->mDvrMQ->commitWrite(ret)) { ALOGE("[DVR] Error: failed to commit write!"); + return 0; } } else { @@ -3524,12 +3533,14 @@ static jlong android_media_tv_Tuner_read_dvr_from_array( static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong size) { sp<Dvr> dvrSp = getDvr(env, dvr); if (dvrSp == NULL) { - ALOGW("Failed to write dvr: dvr not found"); + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to write dvr: dvr not found"); return 0; } if (dvrSp->mDvrMQ == NULL) { - ALOGW("Failed to write dvr: dvr not configured"); + jniThrowException(env, "java/lang/IllegalStateException", + "Failed to write dvr: dvr not configured"); return 0; } @@ -3546,6 +3557,12 @@ static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong si long length = first.getLength(); long firstToRead = std::min(length, toRead); ret = write(dvrSp->mFd, data, firstToRead); + + if (ret < 0) { + ALOGE("[DVR] Failed to write to FD: %s", strerror(errno)); + jniThrowRuntimeException(env, strerror(errno)); + return 0; + } if (ret < firstToRead) { ALOGW("[DVR] MQ to file: %ld bytes read, but %ld bytes written", firstToRead, ret); } else if (firstToRead < toRead) { @@ -3559,6 +3576,7 @@ static jlong android_media_tv_Tuner_write_dvr(JNIEnv *env, jobject dvr, jlong si ALOGD("[DVR] MQ to file: %ld bytes to be read, %ld bytes written", toRead, ret); if (!dvrMq.commitRead(ret)) { ALOGE("[DVR] Error: failed to commit read!"); + return 0; } } else { diff --git a/packages/CarSystemUI/res/values-ar/strings.xml b/packages/CarSystemUI/res/values-ar/strings.xml index 320df5870fe3..57181a8a2fa3 100644 --- a/packages/CarSystemUI/res/values-ar/strings.xml +++ b/packages/CarSystemUI/res/values-ar/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"مستخدم جديد"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"عند إضافة مستخدم جديد، على هذا المستخدم إعداد مساحته."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"يمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-as/strings.xml b/packages/CarSystemUI/res/values-as/strings.xml index 87e27b360ba1..b66bd93cf947 100644 --- a/packages/CarSystemUI/res/values-as/strings.xml +++ b/packages/CarSystemUI/res/values-as/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"নতুন ব্যৱহাৰকাৰী"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰীক যোগ কৰে, তেতিয়া তেওঁ নিজৰ ঠাই ছেট আপ কৰাটো প্ৰয়োজন হয়।"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"যিকোনো ব্যৱহাৰকাৰীয়ে অন্য ব্যৱহাৰকাৰীৰ বাবে এপ্সমূহ আপডে’ট কৰিব পাৰে।"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-az/strings.xml b/packages/CarSystemUI/res/values-az/strings.xml index 98dd49b4f9ff..bc62c8c983ca 100644 --- a/packages/CarSystemUI/res/values-az/strings.xml +++ b/packages/CarSystemUI/res/values-az/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Yeni İstifadəçi"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni istifadəçi əlavə etdiyinizdə həmin şəxs öz yerini təyin etməlidir."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"İstənilən istifadəçi digər bütün istifadəçilər üçün tətbiqləri güncəlləyə bilər."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml index 3f01a3ac4845..9b6a866f89ac 100644 --- a/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/CarSystemUI/res/values-b+sr+Latn/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-be/strings.xml b/packages/CarSystemUI/res/values-be/strings.xml index 1b26c370f958..11f843591888 100644 --- a/packages/CarSystemUI/res/values-be/strings.xml +++ b/packages/CarSystemUI/res/values-be/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Новы карыстальнік"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Калі вы дадаяце новага карыстальніка, яму трэба наладзіць свой профіль."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Кожны карыстальнік прылады можа абнаўляць праграмы для ўсіх іншых карыстальнікаў."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-bg/strings.xml b/packages/CarSystemUI/res/values-bg/strings.xml index dda69ecd7f86..ae2db2d08f25 100644 --- a/packages/CarSystemUI/res/values-bg/strings.xml +++ b/packages/CarSystemUI/res/values-bg/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Нов потребител"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когато добавите нов потребител, той трябва да настрои работната си област."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Всеки потребител може да актуализира приложенията за всички останали потребители."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Зарежда се"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Потребителят се зарежда (от <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-bn/strings.xml b/packages/CarSystemUI/res/values-bn/strings.xml index a41f67262053..263f0a779797 100644 --- a/packages/CarSystemUI/res/values-bn/strings.xml +++ b/packages/CarSystemUI/res/values-bn/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"নতুন ব্যবহারকারী"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"নতুন ব্যবহারকারী যোগ করলে, তার স্পেস তাকে সেট-আপ করে নিতে হবে।"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"যেকোনও ব্যবহারকারী বাকি সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন।"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-bs/strings.xml b/packages/CarSystemUI/res/values-bs/strings.xml index 4b096d6d754c..a8a6f6b0523b 100644 --- a/packages/CarSystemUI/res/values-bs/strings.xml +++ b/packages/CarSystemUI/res/values-bs/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Bilo koji korisnik može ažurirati aplikacije za sve druge korisnike."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ca/strings.xml b/packages/CarSystemUI/res/values-ca/strings.xml index a78bff192757..a4aa731b7fcc 100644 --- a/packages/CarSystemUI/res/values-ca/strings.xml +++ b/packages/CarSystemUI/res/values-ca/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Usuari nou"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar el seu espai."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-cs/strings.xml b/packages/CarSystemUI/res/values-cs/strings.xml index d2fdf36d0dc6..a2c20f6f481e 100644 --- a/packages/CarSystemUI/res/values-cs/strings.xml +++ b/packages/CarSystemUI/res/values-cs/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nový uživatel"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Každý nově přidaný uživatel si musí nastavit vlastní prostor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Každý uživatel může aktualizovat aplikace všech ostatních uživatelů."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-da/strings.xml b/packages/CarSystemUI/res/values-da/strings.xml index 90bd0ac9cb8a..b19cdcba5af9 100644 --- a/packages/CarSystemUI/res/values-da/strings.xml +++ b/packages/CarSystemUI/res/values-da/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Ny bruger"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du tilføjer en ny bruger, skal vedkommende konfigurere sit område."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brugere kan opdatere apps for alle andre brugere."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Indlæser"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Indlæser bruger (fra <xliff:g id="FROM_USER">%1$d</xliff:g> til <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-de/strings.xml b/packages/CarSystemUI/res/values-de/strings.xml index 84c9b785fbee..960f526b2e96 100644 --- a/packages/CarSystemUI/res/values-de/strings.xml +++ b/packages/CarSystemUI/res/values-de/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Neuer Nutzer"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Jeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-el/strings.xml b/packages/CarSystemUI/res/values-el/strings.xml index fcbb0fd4d575..e2d2cec34479 100644 --- a/packages/CarSystemUI/res/values-el/strings.xml +++ b/packages/CarSystemUI/res/values-el/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Νέος χρήστης"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Οποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Φόρτωση"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Φόρτωση χρήστη (από <xliff:g id="FROM_USER">%1$d</xliff:g> έως <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rAU/strings.xml b/packages/CarSystemUI/res/values-en-rAU/strings.xml index a87eb877e7c4..b8bf9906916d 100644 --- a/packages/CarSystemUI/res/values-en-rAU/strings.xml +++ b/packages/CarSystemUI/res/values-en-rAU/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"New user"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rCA/strings.xml b/packages/CarSystemUI/res/values-en-rCA/strings.xml index a87eb877e7c4..b8bf9906916d 100644 --- a/packages/CarSystemUI/res/values-en-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-en-rCA/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"New user"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rGB/strings.xml b/packages/CarSystemUI/res/values-en-rGB/strings.xml index a87eb877e7c4..b8bf9906916d 100644 --- a/packages/CarSystemUI/res/values-en-rGB/strings.xml +++ b/packages/CarSystemUI/res/values-en-rGB/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"New user"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rIN/strings.xml b/packages/CarSystemUI/res/values-en-rIN/strings.xml index a87eb877e7c4..b8bf9906916d 100644 --- a/packages/CarSystemUI/res/values-en-rIN/strings.xml +++ b/packages/CarSystemUI/res/values-en-rIN/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"New user"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-en-rXC/strings.xml b/packages/CarSystemUI/res/values-en-rXC/strings.xml index 6821c3ec0913..1ffa5ebde689 100644 --- a/packages/CarSystemUI/res/values-en-rXC/strings.xml +++ b/packages/CarSystemUI/res/values-en-rXC/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"New User"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"When you add a new user, that person needs to set up their space."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Any user can update apps for all other users."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Loading"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Loading user (from <xliff:g id="FROM_USER">%1$d</xliff:g> to <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-es-rUS/strings.xml b/packages/CarSystemUI/res/values-es-rUS/strings.xml index 060c81272a81..c1c21d17a3a7 100644 --- a/packages/CarSystemUI/res/values-es-rUS/strings.xml +++ b/packages/CarSystemUI/res/values-es-rUS/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Usuario nuevo"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando agregues un usuario nuevo, esa persona deberá configurar su espacio."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario podrá actualizar las apps de otras personas."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Cargando"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Cargando usuario (de <xliff:g id="FROM_USER">%1$d</xliff:g> a <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-es/strings.xml b/packages/CarSystemUI/res/values-es/strings.xml index c3cc86a21063..58aab64b2eef 100644 --- a/packages/CarSystemUI/res/values-es/strings.xml +++ b/packages/CarSystemUI/res/values-es/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nuevo usuario"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cuando añades un usuario, esa persona debe configurar su espacio."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Cualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-et/strings.xml b/packages/CarSystemUI/res/values-et/strings.xml index 1bf7ce523d6a..2fa71a975973 100644 --- a/packages/CarSystemUI/res/values-et/strings.xml +++ b/packages/CarSystemUI/res/values-et/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Uus kasutaja"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Iga kasutaja saab rakendusi värskendada kõigi teiste kasutajate jaoks."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Laadimine"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kasutaja laadimine (<xliff:g id="FROM_USER">%1$d</xliff:g> > <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-eu/strings.xml b/packages/CarSystemUI/res/values-eu/strings.xml index 1786381e4e4d..36bcaae01443 100644 --- a/packages/CarSystemUI/res/values-eu/strings.xml +++ b/packages/CarSystemUI/res/values-eu/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Erabiltzaile berria"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Erabiltzaile bat gehitzen duzunean, bere eremua konfiguratu beharko du."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Edozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Kargatzen"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Erabiltzailea kargatzen (<xliff:g id="FROM_USER">%1$d</xliff:g> izatetik<xliff:g id="TO_USER">%2$d</xliff:g> izatera igaroko da)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fa/strings.xml b/packages/CarSystemUI/res/values-fa/strings.xml index 0bd79ba2d4a0..ec00e29fe0fe 100644 --- a/packages/CarSystemUI/res/values-fa/strings.xml +++ b/packages/CarSystemUI/res/values-fa/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"کاربر جدید"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"وقتی کاربر جدیدی اضافه میکنید، آن فرد باید فضای خود را تنظیم کند."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"هر کاربری میتواند برنامهها را برای همه کاربران دیگر بهروزرسانی کند."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-fi/strings.xml b/packages/CarSystemUI/res/values-fi/strings.xml index 7aa5a5467f65..3cc7f305cdcc 100644 --- a/packages/CarSystemUI/res/values-fi/strings.xml +++ b/packages/CarSystemUI/res/values-fi/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Uusi käyttäjä"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kun lisäät uuden käyttäjän, hänen on valittava oman tilansa asetukset."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Kaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-fr-rCA/strings.xml b/packages/CarSystemUI/res/values-fr-rCA/strings.xml index 22b4409494c6..18e68c07d23d 100644 --- a/packages/CarSystemUI/res/values-fr-rCA/strings.xml +++ b/packages/CarSystemUI/res/values-fr-rCA/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Tout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Chargement en cours…"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Chargement de l\'utilisateur (de <xliff:g id="FROM_USER">%1$d</xliff:g> vers <xliff:g id="TO_USER">%2$d</xliff:g>) en cours…"</string> </resources> diff --git a/packages/CarSystemUI/res/values-fr/strings.xml b/packages/CarSystemUI/res/values-fr/strings.xml index b28c6204d588..1a816955281e 100644 --- a/packages/CarSystemUI/res/values-fr/strings.xml +++ b/packages/CarSystemUI/res/values-fr/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nouvel utilisateur"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"N\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-gl/strings.xml b/packages/CarSystemUI/res/values-gl/strings.xml index d2178ab26746..3fbb291b1162 100644 --- a/packages/CarSystemUI/res/values-gl/strings.xml +++ b/packages/CarSystemUI/res/values-gl/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Novo usuario"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Cando engadas un novo usuario, este deberá configurar o seu espazo."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Calquera usuario pode actualizar as aplicacións para o resto dos usuarios."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-gu/strings.xml b/packages/CarSystemUI/res/values-gu/strings.xml index 5c694830c46f..496f3b5fe603 100644 --- a/packages/CarSystemUI/res/values-gu/strings.xml +++ b/packages/CarSystemUI/res/values-gu/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"નવા વપરાશકર્તા"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિએ તેમની સ્પેસ સેટ કરવાની જરૂર રહે છે."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"કોઈપણ વપરાશકર્તા અન્ય બધા વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-hi/strings.xml b/packages/CarSystemUI/res/values-hi/strings.xml index fc8b4b5e4f30..89b69608efbe 100644 --- a/packages/CarSystemUI/res/values-hi/strings.xml +++ b/packages/CarSystemUI/res/values-hi/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"नया उपयोगकर्ता"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तब उसे अपनी जगह सेट करनी होती है."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"कोई भी उपयोगकर्ता, बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"लोड हो रही है"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"उपयोगकर्ता को लोड किया जा रहा है (<xliff:g id="FROM_USER">%1$d</xliff:g> से <xliff:g id="TO_USER">%2$d</xliff:g> पर)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hr/strings.xml b/packages/CarSystemUI/res/values-hr/strings.xml index befdbe9a3acb..6baec74ddbff 100644 --- a/packages/CarSystemUI/res/values-hr/strings.xml +++ b/packages/CarSystemUI/res/values-hr/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Novi korisnik"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Svaki korisnik može ažurirati aplikacije za ostale korisnike."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Učitavanje"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Učitavanje korisnika (od <xliff:g id="FROM_USER">%1$d</xliff:g> do <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hu/strings.xml b/packages/CarSystemUI/res/values-hu/strings.xml index bd1e6dc735c7..ffa512c4772a 100644 --- a/packages/CarSystemUI/res/values-hu/strings.xml +++ b/packages/CarSystemUI/res/values-hu/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Új felhasználó"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját felületét."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Bármely felhasználó frissítheti az alkalmazásokat az összes felhasználó számára."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Betöltés"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Felhasználó betöltése (<xliff:g id="FROM_USER">%1$d</xliff:g> → <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-hy/strings.xml b/packages/CarSystemUI/res/values-hy/strings.xml index 048d44af7973..2ff1cf16de5c 100644 --- a/packages/CarSystemUI/res/values-hy/strings.xml +++ b/packages/CarSystemUI/res/values-hy/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Նոր օգտատեր"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Երբ դուք նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը։"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Ցանկացած օգտատեր կարող է թարմացնել հավելվածները բոլոր մյուս հաշիվների համար։"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-in/strings.xml b/packages/CarSystemUI/res/values-in/strings.xml index d6d7cfb8be79..901cbe759d63 100644 --- a/packages/CarSystemUI/res/values-in/strings.xml +++ b/packages/CarSystemUI/res/values-in/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baru"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Setiap pengguna dapat mengupdate aplikasi untuk semua pengguna lain."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Memuat"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuat pengguna (dari <xliff:g id="FROM_USER">%1$d</xliff:g> menjadi <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-iw/strings.xml b/packages/CarSystemUI/res/values-iw/strings.xml index 93f2401d51b8..0ca5f2ee8a31 100644 --- a/packages/CarSystemUI/res/values-iw/strings.xml +++ b/packages/CarSystemUI/res/values-iw/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"משתמש חדש"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"בעת הוספת משתמש חדש, על משתמש זה להגדיר את המרחב שלו."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"כל משתמש יכול לעדכן אפליקציות לכל שאר המשתמשים."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ja/strings.xml b/packages/CarSystemUI/res/values-ja/strings.xml index 85bd0bf64f7f..aae7dbff155e 100644 --- a/packages/CarSystemUI/res/values-ja/strings.xml +++ b/packages/CarSystemUI/res/values-ja/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"新しいユーザー"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"どのユーザーも他のすべてのユーザーに代わってアプリを更新できます。"</string> + <string name="car_loading_profile" msgid="4507385037552574474">"読み込んでいます"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"ユーザーを読み込んでいます(<xliff:g id="FROM_USER">%1$d</xliff:g>~<xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ka/strings.xml b/packages/CarSystemUI/res/values-ka/strings.xml index 0e67f2ae8a77..19894d164189 100644 --- a/packages/CarSystemUI/res/values-ka/strings.xml +++ b/packages/CarSystemUI/res/values-ka/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"ახალი მომხმარებელი"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის გამართვა მოუწევს."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"იტვირთება"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"იტვირთება მომხმარებელი (<xliff:g id="FROM_USER">%1$d</xliff:g>-დან <xliff:g id="TO_USER">%2$d</xliff:g>-მდე)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-kk/strings.xml b/packages/CarSystemUI/res/values-kk/strings.xml index 94a192ee8df4..8b6cde803702 100644 --- a/packages/CarSystemUI/res/values-kk/strings.xml +++ b/packages/CarSystemUI/res/values-kk/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Жаңа пайдаланушы"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Енгізілген жаңа пайдаланушы өз профилін реттеуі керек."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Кез келген пайдаланушы қолданбаларды басқа пайдаланушылар үшін жаңарта алады."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-km/strings.xml b/packages/CarSystemUI/res/values-km/strings.xml index 47b659f47f76..fbcab8431476 100644 --- a/packages/CarSystemUI/res/values-km/strings.xml +++ b/packages/CarSystemUI/res/values-km/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"អ្នកប្រើប្រាស់ថ្មី"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"នៅពេលដែលអ្នកបញ្ចូលអ្នកប្រើប្រាស់ថ្មី បុគ្គលនោះត្រូវតែរៀបចំទំហំផ្ទុករបស់គេ។"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"អ្នកប្រើប្រាស់ណាក៏អាចដំឡើងកំណែកម្មវិធីសម្រាប់អ្នកប្រើប្រាស់ទាំងអស់ផ្សេងទៀតបានដែរ។"</string> + <string name="car_loading_profile" msgid="4507385037552574474">"កំពុងផ្ទុក"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"កំពុងផ្ទុកអ្នកប្រើប្រាស់ (ពី <xliff:g id="FROM_USER">%1$d</xliff:g> ដល់ <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-kn/strings.xml b/packages/CarSystemUI/res/values-kn/strings.xml index 50e1721874ca..c3cb3834c820 100644 --- a/packages/CarSystemUI/res/values-kn/strings.xml +++ b/packages/CarSystemUI/res/values-kn/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"ಹೊಸ ಬಳಕೆದಾರ"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ನೀವು ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಆ್ಯಪ್ಗಳನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಬಹುದು."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ko/strings.xml b/packages/CarSystemUI/res/values-ko/strings.xml index 75b16a821ea1..6b670b018814 100644 --- a/packages/CarSystemUI/res/values-ko/strings.xml +++ b/packages/CarSystemUI/res/values-ko/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"신규 사용자"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"추가된 신규 사용자는 자신만의 공간을 설정해야 합니다."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"누구나 다른 모든 사용자를 위해 앱을 업데이트할 수 있습니다."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"로드 중"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"사용자 로드 중(<xliff:g id="FROM_USER">%1$d</xliff:g>님에서 <xliff:g id="TO_USER">%2$d</xliff:g>님으로)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ky/strings.xml b/packages/CarSystemUI/res/values-ky/strings.xml index e9da09d03456..8447f7de35c4 100644 --- a/packages/CarSystemUI/res/values-ky/strings.xml +++ b/packages/CarSystemUI/res/values-ky/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Жаңы колдонуучу"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Жаңы колдонуучу кошулганда, ал өзүнүн профилин жөндөп алышы керек."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Колдонмолорду бир колдонуучу калган бардык колдонуучулар үчүн да жаңырта алат."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-lo/strings.xml b/packages/CarSystemUI/res/values-lo/strings.xml index 1721377c11e1..ea8e0fb4207e 100644 --- a/packages/CarSystemUI/res/values-lo/strings.xml +++ b/packages/CarSystemUI/res/values-lo/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"ຜູ້ໃຊ້ໃໝ່"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ເມື່ອທ່ານເພີ່ມຜູ້ໃຊ້ໃໝ່, ບຸກຄົນນັ້ນຈຳເປັນຕ້ອງຕັ້ງຄ່າພື້ນທີ່ຂອງເຂົາເຈົ້າ."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ຜູ້ໃຊ້ຕ່າງໆສາມາດອັບເດດແອັບສຳລັບຜູ້ໃຊ້ອື່ນທັງໝົດໄດ້."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-lv/strings.xml b/packages/CarSystemUI/res/values-lv/strings.xml index 8a0be70f54ab..d7b4619fab89 100644 --- a/packages/CarSystemUI/res/values-lv/strings.xml +++ b/packages/CarSystemUI/res/values-lv/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Jauns lietotājs"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kad pievienojat jaunu lietotāju, viņam ir jāizveido savs profils."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Ikviens lietotājs var atjaunināt lietotnes visu lietotāju vārdā."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-mk/strings.xml b/packages/CarSystemUI/res/values-mk/strings.xml index 63cea06f7371..f8fd02cb071d 100644 --- a/packages/CarSystemUI/res/values-mk/strings.xml +++ b/packages/CarSystemUI/res/values-mk/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Нов корисник"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Кога додавате нов корисник, тоа лице треба да го постави својот простор."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Секој корисник може да ажурира апликации за сите други корисници."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Се вчитува"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Се вчитува корисникот (од <xliff:g id="FROM_USER">%1$d</xliff:g> до <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ml/strings.xml b/packages/CarSystemUI/res/values-ml/strings.xml index 9ee3430443de..7273241836e5 100644 --- a/packages/CarSystemUI/res/values-ml/strings.xml +++ b/packages/CarSystemUI/res/values-ml/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"പുതിയ ഉപയോക്താവ്"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"നിങ്ങളൊരു പുതിയ ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തി സ്വന്തം ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ഏതൊരു ഉപയോക്താവിനും മറ്റെല്ലാ ഉപയോക്താക്കൾക്കുമായി ആപ്പുകൾ അപ്ഡേറ്റ് ചെയ്യാനാവും."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-mn/strings.xml b/packages/CarSystemUI/res/values-mn/strings.xml index bae5c64f8cdf..5bd76dc7e067 100644 --- a/packages/CarSystemUI/res/values-mn/strings.xml +++ b/packages/CarSystemUI/res/values-mn/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Шинэ хэрэглэгч"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Та шинэ хэрэглэгч нэмэх үед тухайн хэрэглэгч хувийн орон зайгаа тохируулах шаардлагатай."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Бусад бүх хэрэглэгчийн аппыг дурын хэрэглэгч шинэчлэх боломжтой."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Ачаалж байна"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Хэрэглэгчийг ачаалж байна (<xliff:g id="FROM_USER">%1$d</xliff:g>-с <xliff:g id="TO_USER">%2$d</xliff:g> хүртэл)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-mr/strings.xml b/packages/CarSystemUI/res/values-mr/strings.xml index 27ee0a935018..14a4002fbff0 100644 --- a/packages/CarSystemUI/res/values-mr/strings.xml +++ b/packages/CarSystemUI/res/values-mr/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"नवीन वापरकर्ता"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"तुम्ही नवीन वापरकर्ता जोडता तेव्हा त्या व्यक्तीने त्यांची जागा सेट करणे आवश्यक असते."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"कोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ms/strings.xml b/packages/CarSystemUI/res/values-ms/strings.xml index 868a0605b433..29ac83afc12c 100644 --- a/packages/CarSystemUI/res/values-ms/strings.xml +++ b/packages/CarSystemUI/res/values-ms/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Pengguna Baharu"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Apabila anda menambahkan pengguna baharu, orang itu perlu menyediakan ruang mereka."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Mana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Memuatkan"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Memuatkan pengguna (daripada <xliff:g id="FROM_USER">%1$d</xliff:g> hingga <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-my/strings.xml b/packages/CarSystemUI/res/values-my/strings.xml index 231b41f06aab..ba161558d6e4 100644 --- a/packages/CarSystemUI/res/values-my/strings.xml +++ b/packages/CarSystemUI/res/values-my/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"အသုံးပြုသူ အသစ်"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"အသုံးပြုသူအသစ် ထည့်သည့်အခါ ထိုသူသည် မိမိ၏ နေရာကို စနစ်ထည့်သွင်းရပါမည်။"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"မည်သူမဆို အသုံးပြုသူအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-nb/strings.xml b/packages/CarSystemUI/res/values-nb/strings.xml index 9141cfc11d2a..a882b83dd52f 100644 --- a/packages/CarSystemUI/res/values-nb/strings.xml +++ b/packages/CarSystemUI/res/values-nb/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Ny bruker"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Alle brukere kan oppdatere apper for alle andre brukere."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ne/strings.xml b/packages/CarSystemUI/res/values-ne/strings.xml index 231559d7f821..f9eef4262ca9 100644 --- a/packages/CarSystemUI/res/values-ne/strings.xml +++ b/packages/CarSystemUI/res/values-ne/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"नयाँ प्रयोगकर्ता"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"तपाईंले नयाँ प्रयोगकर्ता थप्दा ती व्यक्तिले आफ्नो स्थान सेटअप गर्नु पर्छ।"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"सबै प्रयोगकर्ताले अन्य प्रयोगकर्ताका अनुप्रयोगहरू अद्यावधिक गर्न सक्छन्।"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-nl/strings.xml b/packages/CarSystemUI/res/values-nl/strings.xml index 5ba7ce41b37c..95a76467b078 100644 --- a/packages/CarSystemUI/res/values-nl/strings.xml +++ b/packages/CarSystemUI/res/values-nl/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Nieuwe gebruiker"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Als je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Elke gebruiker kan apps updaten voor alle andere gebruikers"</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Laden"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Gebruiker laden (van <xliff:g id="FROM_USER">%1$d</xliff:g> naar <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-or/strings.xml b/packages/CarSystemUI/res/values-or/strings.xml index 1badbf9ef07f..af895d0a74f9 100644 --- a/packages/CarSystemUI/res/values-or/strings.xml +++ b/packages/CarSystemUI/res/values-or/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"ନୂଆ ଉପଯୋଗକର୍ତ୍ତା"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କରିବା ବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ତାଙ୍କ ସ୍ଥାନ ସେଟ୍ ଅପ୍ କରିବାର ଆବଶ୍ୟକତା ଅଛି।"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍ କରିପାରିବେ।"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-pa/strings.xml b/packages/CarSystemUI/res/values-pa/strings.xml index 4687aa768483..446b49c2d0e1 100644 --- a/packages/CarSystemUI/res/values-pa/strings.xml +++ b/packages/CarSystemUI/res/values-pa/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"ਨਵਾਂ ਵਰਤੋਂਕਾਰ"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ਜਦੋਂ ਤੁਸੀਂ ਕੋਈ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸੈੱਟਅੱਪ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-pl/strings.xml b/packages/CarSystemUI/res/values-pl/strings.xml index 35d735b38dac..9de0b02b7b45 100644 --- a/packages/CarSystemUI/res/values-pl/strings.xml +++ b/packages/CarSystemUI/res/values-pl/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nowy użytkownik"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Każdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-pt-rPT/strings.xml b/packages/CarSystemUI/res/values-pt-rPT/strings.xml index 7b0ee14e9a94..182f5b58d1b1 100644 --- a/packages/CarSystemUI/res/values-pt-rPT/strings.xml +++ b/packages/CarSystemUI/res/values-pt-rPT/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Novo utilizador"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer utilizador pode atualizar apps para todos os outros utilizadores."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"A carregar…"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"A carregar o utilizador (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)…"</string> </resources> diff --git a/packages/CarSystemUI/res/values-pt/strings.xml b/packages/CarSystemUI/res/values-pt/strings.xml index fab603d2b389..5c8394a51599 100644 --- a/packages/CarSystemUI/res/values-pt/strings.xml +++ b/packages/CarSystemUI/res/values-pt/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Novo usuário"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Quando você adiciona um usuário novo, essa pessoa precisa configurar o espaço dela."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Qualquer usuário pode atualizar apps para os demais usuários."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Carregando"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Carregando usuário (de <xliff:g id="FROM_USER">%1$d</xliff:g> para <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ro/strings.xml b/packages/CarSystemUI/res/values-ro/strings.xml index adf83a323905..b5efb3c71e82 100644 --- a/packages/CarSystemUI/res/values-ro/strings.xml +++ b/packages/CarSystemUI/res/values-ro/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Utilizator nou"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Orice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ru/strings.xml b/packages/CarSystemUI/res/values-ru/strings.xml index 69ee939de3db..1397ab5d8c90 100644 --- a/packages/CarSystemUI/res/values-ru/strings.xml +++ b/packages/CarSystemUI/res/values-ru/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Новый пользователь"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Когда вы добавите пользователя, ему потребуется настроить профиль."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Любой пользователь устройства может обновлять приложения для всех аккаунтов."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-si/strings.xml b/packages/CarSystemUI/res/values-si/strings.xml index 061d4ed685e1..947cb0a53206 100644 --- a/packages/CarSystemUI/res/values-si/strings.xml +++ b/packages/CarSystemUI/res/values-si/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"නව පරිශීලක"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"ඔබ අලුත් පරිශීලකයෙකු එක් කරන විට, එම පුද්ගලයා තමන්ගේ ඉඩ සකසා ගැනීමට අවශ්ය වේ."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"සියලුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යෙදුම් යාවත්කාලීන කළ හැක."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"පූරණය වෙමින්"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"පරිශීලකයා පූරණය වෙමින් (<xliff:g id="FROM_USER">%1$d</xliff:g> සිට <xliff:g id="TO_USER">%2$d</xliff:g> වෙත)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-sk/strings.xml b/packages/CarSystemUI/res/values-sk/strings.xml index b5e9416fcd40..1ce7f1eddedc 100644 --- a/packages/CarSystemUI/res/values-sk/strings.xml +++ b/packages/CarSystemUI/res/values-sk/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nový používateľ"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Ktorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-sl/strings.xml b/packages/CarSystemUI/res/values-sl/strings.xml index b386591d369e..3f2c0f4c2c5d 100644 --- a/packages/CarSystemUI/res/values-sl/strings.xml +++ b/packages/CarSystemUI/res/values-sl/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Nov uporabnik"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Vsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-sq/strings.xml b/packages/CarSystemUI/res/values-sq/strings.xml index 21484f2b6402..a9fa951970c0 100644 --- a/packages/CarSystemUI/res/values-sq/strings.xml +++ b/packages/CarSystemUI/res/values-sq/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Përdorues i ri"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Çdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-sr/strings.xml b/packages/CarSystemUI/res/values-sr/strings.xml index 20969672eef3..0a9c2eb12ed4 100644 --- a/packages/CarSystemUI/res/values-sr/strings.xml +++ b/packages/CarSystemUI/res/values-sr/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Нови корисник"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Када додате новог корисника, та особа треба да подеси свој простор."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Сваки корисник може да ажурира апликације за све остале кориснике."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-sv/strings.xml b/packages/CarSystemUI/res/values-sv/strings.xml index af3f5b87b853..349218b8fe82 100644 --- a/packages/CarSystemUI/res/values-sv/strings.xml +++ b/packages/CarSystemUI/res/values-sv/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Ny användare"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Alla användare kan uppdatera appar för andra användare."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-sw/strings.xml b/packages/CarSystemUI/res/values-sw/strings.xml index 1aa086819784..1466f13c4c0f 100644 --- a/packages/CarSystemUI/res/values-sw/strings.xml +++ b/packages/CarSystemUI/res/values-sw/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"Mtumiaji Mpya"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Ukiongeza mtumiaji mpya, ni lazima aweke kikundi chake."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Mtumiaji yeyote anaweza kusasisha programu za watumiaji wengine."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-ta/strings.xml b/packages/CarSystemUI/res/values-ta/strings.xml index 9f76f777a9d1..849b40d36ccd 100644 --- a/packages/CarSystemUI/res/values-ta/strings.xml +++ b/packages/CarSystemUI/res/values-ta/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"புதிய பயனர்"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"புதிய பயனரைச் சேர்க்கும்போது அவர் தனக்கான சேமிப்பிடத்தை அமைக்க வேண்டும்."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"எந்தப் பயனரும் பிற பயனர்கள் சார்பாக ஆப்ஸைப் புதுப்பிக்க முடியும்."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"ஏற்றுகிறது"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"பயனர் தகவலை ஏற்றுகிறது (<xliff:g id="FROM_USER">%1$d</xliff:g>லிருந்து <xliff:g id="TO_USER">%2$d</xliff:g> வரை)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-te/strings.xml b/packages/CarSystemUI/res/values-te/strings.xml index e819034c9b40..ea04cc0f7354 100644 --- a/packages/CarSystemUI/res/values-te/strings.xml +++ b/packages/CarSystemUI/res/values-te/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"కొత్త యూజర్"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"మీరు కొత్త యూజర్ను జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్ను సెటప్ చేసుకోవాలి."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ఏ యూజర్ అయినా మిగతా యూజర్ల కోసం యాప్లను అప్డేట్ చేయవచ్చు."</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-th/strings.xml b/packages/CarSystemUI/res/values-th/strings.xml index 57ac7dc72cc6..fa99ac1928c1 100644 --- a/packages/CarSystemUI/res/values-th/strings.xml +++ b/packages/CarSystemUI/res/values-th/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"ผู้ใช้ใหม่"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"ผู้ใช้ทุกคนจะอัปเดตแอปให้แก่ผู้ใช้คนอื่นๆ ได้"</string> + <string name="car_loading_profile" msgid="4507385037552574474">"กำลังโหลด"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"กำลังโหลดผู้ใช้ (จาก <xliff:g id="FROM_USER">%1$d</xliff:g> ถึง <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-tl/strings.xml b/packages/CarSystemUI/res/values-tl/strings.xml index 5e0af6d6c266..c6f5f59acf0d 100644 --- a/packages/CarSystemUI/res/values-tl/strings.xml +++ b/packages/CarSystemUI/res/values-tl/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Bagong User"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Puwedeng i-update ng sinumang user ang mga app para sa lahat ng iba pang user."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Naglo-load"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Nilo-load ang user (mula kay <xliff:g id="FROM_USER">%1$d</xliff:g> papunta kay <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-tr/strings.xml b/packages/CarSystemUI/res/values-tr/strings.xml index 7949329ba1c3..a76812769dae 100644 --- a/packages/CarSystemUI/res/values-tr/strings.xml +++ b/packages/CarSystemUI/res/values-tr/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Yeni Kullanıcı"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yeni kullanıcı eklediğinizde, bu kişinin alanını ayarlaması gerekir."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Herhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Yükleniyor"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Kullanıcı yükleniyor (<xliff:g id="FROM_USER">%1$d</xliff:g> kullanıcısından <xliff:g id="TO_USER">%2$d</xliff:g> kullanıcısına)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-ur/strings.xml b/packages/CarSystemUI/res/values-ur/strings.xml index ddfccdcbee7d..b052c0fc445b 100644 --- a/packages/CarSystemUI/res/values-ur/strings.xml +++ b/packages/CarSystemUI/res/values-ur/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"نیا صارف"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ سیٹ کرنی ہوتی ہے۔"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"کوئی بھی صارف دیگر سبھی صارفین کے لیے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-uz/strings.xml b/packages/CarSystemUI/res/values-uz/strings.xml index e0f8378879d6..adef2add435f 100644 --- a/packages/CarSystemUI/res/values-uz/strings.xml +++ b/packages/CarSystemUI/res/values-uz/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Yangi foydalanuvchi"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Yangi profil kiritilgach, uni sozlash lozim."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Qurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Yuklanmoqda"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Foydalanuvchi profili yuklanmoqda (<xliff:g id="FROM_USER">%1$d</xliff:g> – <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-vi/strings.xml b/packages/CarSystemUI/res/values-vi/strings.xml index ce1826bc5ee3..616b48fd17b6 100644 --- a/packages/CarSystemUI/res/values-vi/strings.xml +++ b/packages/CarSystemUI/res/values-vi/strings.xml @@ -26,4 +26,6 @@ <string name="car_new_user" msgid="6637442369728092473">"Người dùng mới"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"Khi bạn thêm một người dùng mới, người đó cần thiết lập không gian của mình."</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"Bất kỳ người dùng nào cũng có thể cập nhật ứng dụng cho tất cả những người dùng khác."</string> + <string name="car_loading_profile" msgid="4507385037552574474">"Đang tải"</string> + <string name="car_loading_profile_developer_message" msgid="1660962766911529611">"Đang tải hồ sơ người dùng (từ <xliff:g id="FROM_USER">%1$d</xliff:g> sang <xliff:g id="TO_USER">%2$d</xliff:g>)"</string> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rCN/strings.xml b/packages/CarSystemUI/res/values-zh-rCN/strings.xml index 431fd62ea9d2..5bdc384ab13d 100644 --- a/packages/CarSystemUI/res/values-zh-rCN/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rCN/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"新用户"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"当您添加新用户时,该用户需要自行设置个人空间。"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"任何用户均可为所有其他用户更新应用。"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rHK/strings.xml b/packages/CarSystemUI/res/values-zh-rHK/strings.xml index 24efc22e67d8..74a70e27614b 100644 --- a/packages/CarSystemUI/res/values-zh-rHK/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rHK/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"新增的使用者需要自行設定個人空間。"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都可以為所有其他使用者更新應用程式。"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CarSystemUI/res/values-zh-rTW/strings.xml b/packages/CarSystemUI/res/values-zh-rTW/strings.xml index e1356cafde26..c93862bbd816 100644 --- a/packages/CarSystemUI/res/values-zh-rTW/strings.xml +++ b/packages/CarSystemUI/res/values-zh-rTW/strings.xml @@ -26,4 +26,8 @@ <string name="car_new_user" msgid="6637442369728092473">"新使用者"</string> <string name="user_add_user_message_setup" msgid="1035578846007352323">"新使用者必須自行設定個人空間。"</string> <string name="user_add_user_message_update" msgid="7061671307004867811">"任何使用者都能為所有其他使用者更新應用程式。"</string> + <!-- no translation found for car_loading_profile (4507385037552574474) --> + <skip /> + <!-- no translation found for car_loading_profile_developer_message (1660962766911529611) --> + <skip /> </resources> diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk Binary files differindex e153c910d10a..180dfb672c7f 100644 --- a/packages/CtsShim/apk/arm/CtsShim.apk +++ b/packages/CtsShim/apk/arm/CtsShim.apk diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk Binary files differindex 7fbeb3da05a3..d87ea7fcef89 100644 --- a/packages/CtsShim/apk/arm/CtsShimPriv.apk +++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk Binary files differindex e153c910d10a..180dfb672c7f 100644 --- a/packages/CtsShim/apk/x86/CtsShim.apk +++ b/packages/CtsShim/apk/x86/CtsShim.apk diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk Binary files differindex f0eaf02e0be5..3124651fe425 100644 --- a/packages/CtsShim/apk/x86/CtsShimPriv.apk +++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk diff --git a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java index 57d95942bcb9..4f86afaa995c 100644 --- a/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java @@ -67,7 +67,7 @@ public class BrightnessUtils { /** * Version of {@link #convertGammaToLinear} that takes and returns float values. - * TODO: brightnessfloat Merge with above method later. + * TODO(flc): refactor Android Auto to use float version * * @param val The slider value. * @param min The minimum acceptable value for the setting. @@ -83,9 +83,13 @@ public class BrightnessUtils { ret = MathUtils.exp((normalizedVal - C) / A) + B; } - // HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1] + // HLG is normalized to the range [0, 12], ensure that value is within that range, + // it shouldn't be out of bounds. + final float normalizedRet = MathUtils.constrain(ret, 0, 12); + + // Re-normalize to the range [0, 1] // in order to derive the correct setting value. - return MathUtils.lerp(min, max, ret / 12); + return MathUtils.lerp(min, max, normalizedRet / 12); } /** @@ -111,16 +115,7 @@ public class BrightnessUtils { * @return The corresponding slider value */ public static final int convertLinearToGamma(int val, int min, int max) { - // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1] - final float normalizedVal = MathUtils.norm(min, max, val) * 12; - final float ret; - if (normalizedVal <= 1f) { - ret = MathUtils.sqrt(normalizedVal) * R; - } else { - ret = A * MathUtils.log(normalizedVal - B) + C; - } - - return Math.round(MathUtils.lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret)); + return convertLinearToGammaFloat((float) val, (float) min, (float) max); } /** diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java index 197e34df22a8..7d95f1992aaf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java @@ -15,6 +15,8 @@ */ package com.android.settingslib.media; +import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR; + import android.app.Notification; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -448,6 +450,8 @@ public class LocalMediaManager implements BluetoothCallback { if (mOnTransferBluetoothDevice != null && mOnTransferBluetoothDevice.isConnected()) { connectDevice(mOnTransferBluetoothDevice); mOnTransferBluetoothDevice.setState(MediaDeviceState.STATE_CONNECTED); + dispatchSelectedDeviceStateChanged(mOnTransferBluetoothDevice, + MediaDeviceState.STATE_CONNECTED); mOnTransferBluetoothDevice = null; } } @@ -626,6 +630,7 @@ public class LocalMediaManager implements BluetoothCallback { // Failed to connect mOnTransferBluetoothDevice.setState(MediaDeviceState.STATE_DISCONNECTED); mOnTransferBluetoothDevice = null; + dispatchOnRequestFailed(REASON_UNKNOWN_ERROR); } dispatchDeviceAttributesChanged(); } diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java index 139a12c44e0f..8a178a9a81f2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java @@ -49,7 +49,8 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { private static final String TAG = "MediaDevice"; @Retention(RetentionPolicy.SOURCE) - @IntDef({MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE, + @IntDef({MediaDeviceType.TYPE_UNKNOWN, + MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE, MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE, MediaDeviceType.TYPE_FAST_PAIR_BLUETOOTH_DEVICE, MediaDeviceType.TYPE_BLUETOOTH_DEVICE, @@ -57,6 +58,7 @@ public abstract class MediaDevice implements Comparable<MediaDevice> { MediaDeviceType.TYPE_CAST_GROUP_DEVICE, MediaDeviceType.TYPE_PHONE_DEVICE}) public @interface MediaDeviceType { + int TYPE_UNKNOWN = 0; int TYPE_USB_C_AUDIO_DEVICE = 1; int TYPE_3POINT5_MM_AUDIO_DEVICE = 2; int TYPE_FAST_PAIR_BLUETOOTH_DEVICE = 3; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java index c0924d9a8b35..1b20f2c0a533 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/display/BrightnessUtilsTest.java @@ -17,6 +17,7 @@ package com.android.settingslib.display; import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX; +import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MIN; import static com.google.common.truth.Truth.assertThat; @@ -27,26 +28,40 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class BrightnessUtilsTest { - private static final int MIN = 1; - private static final int MAX = 255; + private static final int MIN_INT = 1; + private static final int MAX_INT = 255; + private static final float MIN_FLOAT = 0.0f; + private static final float MAX_FLOAT = 1.0f; @Test - public void linearToGamma_minValue_shouldReturn0() { - assertThat(BrightnessUtils.convertLinearToGamma(MIN, MIN, MAX)).isEqualTo(0); + public void linearToGamma_minValue_shouldReturnMin() { + assertThat(BrightnessUtils.convertLinearToGamma(MIN_INT, MIN_INT, MAX_INT)) + .isEqualTo(GAMMA_SPACE_MIN); + assertThat(BrightnessUtils.convertLinearToGammaFloat(MIN_FLOAT, MIN_FLOAT, MAX_FLOAT)) + .isEqualTo(GAMMA_SPACE_MIN); } @Test public void linearToGamma_maxValue_shouldReturnGammaSpaceMax() { - assertThat(BrightnessUtils.convertLinearToGamma(MAX, MIN, MAX)).isEqualTo(GAMMA_SPACE_MAX); + assertThat(BrightnessUtils.convertLinearToGamma(MAX_INT, MIN_INT, MAX_INT)) + .isEqualTo(GAMMA_SPACE_MAX); + assertThat(BrightnessUtils.convertLinearToGammaFloat(MAX_FLOAT, MIN_FLOAT, MAX_FLOAT)) + .isEqualTo(GAMMA_SPACE_MAX); } @Test public void gammaToLinear_minValue_shouldReturnMin() { - assertThat(BrightnessUtils.convertGammaToLinear(MIN, MIN, MAX)).isEqualTo(MIN); + assertThat(BrightnessUtils.convertGammaToLinear(GAMMA_SPACE_MIN, MIN_INT, MAX_INT)) + .isEqualTo(MIN_INT); + assertThat(BrightnessUtils.convertGammaToLinearFloat(GAMMA_SPACE_MIN, MIN_FLOAT, MAX_FLOAT)) + .isEqualTo(MIN_FLOAT); } @Test public void gammaToLinear_gammaSpaceValue_shouldReturnMax() { - assertThat(BrightnessUtils.convertGammaToLinear(GAMMA_SPACE_MAX, MIN, MAX)).isEqualTo(MAX); + assertThat(BrightnessUtils.convertGammaToLinear(GAMMA_SPACE_MAX, MIN_INT, MAX_INT)) + .isEqualTo(MAX_INT); + assertThat(BrightnessUtils.convertGammaToLinearFloat(GAMMA_SPACE_MAX, MIN_FLOAT, MAX_FLOAT)) + .isEqualTo(MAX_FLOAT); } } diff --git a/packages/SystemUI/res/drawable/control_spinner_background.xml b/packages/SystemUI/res/drawable/control_spinner_background.xml index 7a8728d2983c..46a9dad29fec 100644 --- a/packages/SystemUI/res/drawable/control_spinner_background.xml +++ b/packages/SystemUI/res/drawable/control_spinner_background.xml @@ -21,11 +21,6 @@ android:paddingLeft="0dp" android:paddingRight="0dp"> <item - android:gravity="end|fill_vertical" - android:width="40dp" - android:drawable="@*android:drawable/control_background_40dp_material" /> - - <item android:drawable="@drawable/ic_ksh_key_down" android:gravity="end|bottom" android:paddingBottom="6dp" diff --git a/packages/SystemUI/res/drawable/pip_resize_handle.xml b/packages/SystemUI/res/drawable/pip_resize_handle.xml new file mode 100644 index 000000000000..0a8cbc429dd8 --- /dev/null +++ b/packages/SystemUI/res/drawable/pip_resize_handle.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright (C) 2020 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="12.0dp" + android:height="12.0dp" + android:viewportWidth="12" + android:viewportHeight="12"> + <group + android:translateX="12" + android:rotation="90"> + <path + android:fillColor="#FFFFFF" + android:pathData="M3.41421 0L2 1.41422L10.4853 9.8995L11.8995 8.48528L3.41421 0ZM2.41421 4.24268L1 5.65689L6.65685 11.3137L8.07107 9.89953L2.41421 4.24268Z" /> + </group> +</vector> diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml index ee0bd14820bd..179e8fe4de2a 100644 --- a/packages/SystemUI/res/layout/pip_menu_activity.xml +++ b/packages/SystemUI/res/layout/pip_menu_activity.xml @@ -81,4 +81,13 @@ android:src="@drawable/ic_close_white" android:background="?android:selectableItemBackgroundBorderless" /> + <!--TODO (b/156917828): Add content description for a11y purposes?--> + <ImageButton + android:id="@+id/resize_handle" + android:layout_width="@dimen/pip_action_size" + android:layout_height="@dimen/pip_action_size" + android:layout_gravity="top|start" + android:padding="@dimen/pip_action_padding" + android:src="@drawable/pip_resize_handle" + android:background="?android:selectableItemBackgroundBorderless" /> </FrameLayout> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 4d128ceb7b79..0a7c40493c20 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroles bygevoeg.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrole bygevoeg.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"As gunsteling gemerk; posisie <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"As gunsteling ontmerk"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"gunsteling"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ontmerk as gunsteling"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Skuif na posisie <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontroles"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Kies kontroles om toegang vanaf die aan/af-kieslys te kry"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hou en sleep om kontroles te herrangskik"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index f811dc76e0da..364a0a838cbc 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ቁጥጥሮች ታክለዋል።</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ቁጥጥሮች ታክለዋል።</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ተወዳጅ አልተደረገም"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ተወዳጅ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ተወዳጅ አታድርግ"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ወደ ቦታ <xliff:g id="NUMBER">%d</xliff:g> ውሰድ"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"መቆጣጠሪያዎች"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ከኃይል ምናሌ ላይ ለመድረስ መቆጣጠሪያዎችን ይምረጡ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"መቆጣጠሪያዎችን ዳግም ለማስተካከል ይያዙ እና ይጎትቱ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 749241da097a..67cf15c7defc 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -722,7 +722,7 @@ <string name="notification_alert_title" msgid="7629202599338071971">"إشعار مصحوب بتنبيه صوتي"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"فقاعة"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"يساعدك هذا الإشعار على التركيز بدون صوت أو اهتزاز."</string> - <string name="notification_channel_summary_default" msgid="3539949463907902037">"يلفت هذا الإشعار انتباهك باستخدام الصوت والاهتزاز."</string> + <string name="notification_channel_summary_default" msgid="3539949463907902037">"يلفت هذا الإشعار انتباهك من خلال صوت أو اهتزاز."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"يلفت هذا الإشعار انتباهك باستخدام الصوت والاهتزاز. تظهر المحادثات من <xliff:g id="APP_NAME">%1$s</xliff:g> كفقاعات تلقائيًا."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"يلفِت هذا الإشعار انتباهك لهذا المحتوى باستخدام اختصار عائم."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"تظهر كفقاعة محادثة في أعلى قسم المحادثات"</string> @@ -1051,6 +1051,13 @@ <item quantity="other">تمت إضافة <xliff:g id="NUMBER_1">%s</xliff:g> عنصر تحكّم.</item> <item quantity="one">تمت إضافة عنصر تحكّم واحد (<xliff:g id="NUMBER_0">%s</xliff:g>).</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"تمت الإضافة إلى المفضّلة، الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"تمت الإزالة من المفضّلة"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"إضافة إلى المُفضلة"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"إزالة من المفضّلة"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"نقل إلى الموضع <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"عناصر التحكّم"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"اختيار عناصر التحكّم التي تريد الوصول إليها من قائمة التشغيل"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"اضغط مع الاستمرار واسحب لإعادة ترتيب عناصر التحكّم."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 92be0fef3eb6..edd8a85b065b 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> টা নিয়ন্ত্ৰণ যোগ কৰা হ’ল।</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> টা নিয়ন্ত্ৰণ যোগ কৰা হ’ল।</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল, স্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"অপ্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"প্ৰিয়"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"অপ্ৰিয়"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> নম্বৰ অৱস্থানলৈ স্থানান্তৰিত কৰক"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"নিয়ন্ত্ৰণসমূহ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"পাৱাৰ মেনুখনৰ পৰা এক্সেছ পাবলৈ নিয়ন্ত্ৰণসমূহ বাছনি কৰক"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"নিয়ন্ত্ৰণসমূহ পুনৰ সজাবলৈ ধৰি ৰাখক আৰু টানি আনি এৰক"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 9230d4ca12c7..68e82a17b1cf 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -1013,7 +1013,7 @@ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Söhbət bölməsinin yuxarısında göstərilir"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Kilid ekranında profil şəkli göstərilir"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Tətbiqlərin üzərində üzən qabarcıq kimi görünəcək"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Narahat Etməyin rejimi bölünsün"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Narahat Etməyin rejimində göstərilsin"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Anladım"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Böyütmə Üst-üstə Düşən Pəncərəsi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Böyütmə Pəncərəsi"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> nizamlayıcı əlavə edilib.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> nizamlayıcı əlavə edilib.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Silinib"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Sevimlilərə əlavə edilib, sıra: <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Sevimlilərdən silinib"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"sevimli"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"sevimlilərdən silin"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> mövqeyinə keçirin"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Nizamlayıcılar"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Enerji menyusundan daxil olacağınız nizamlayıcıları seçin"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Nizamlayıcıları yenidən tənzimləmək üçün tutub sürüşdürün"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index b633bb6804ee..bdeca46a98ab 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -1033,6 +1033,13 @@ <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> kontrole su dodate.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrola je dodato.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Označeno je kao omiljeno, <xliff:g id="NUMBER">%d</xliff:g>. pozicija"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno je iz omiljenih"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"označili kao omiljeno"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonili iz omiljenih"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Premestite na <xliff:g id="NUMBER">%d</xliff:g>. poziciju"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Odaberite kontrole kojima ćete pristupati iz menija napajanja"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i prevucite da biste promenili raspored kontrola"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index df9a660c6d13..ae90a46aed7f 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -699,7 +699,7 @@ <string name="notification_channel_unsilenced" msgid="94878840742161152">"Гэтыя апавяшчэнні будуць паказвацца з гукам"</string> <string name="inline_blocking_helper" msgid="2891486013649543452">"Звычайна вы адхіляеце гэтыя апавяшчэнні. \nПаказваць іх?"</string> <string name="inline_done_button" msgid="6043094985588909584">"Гатова"</string> - <string name="inline_ok_button" msgid="603075490581280343">"Ужыць"</string> + <string name="inline_ok_button" msgid="603075490581280343">"Прымяніць"</string> <string name="inline_keep_showing" msgid="8736001253507073497">"Працягваць паказваць гэтыя апавяшчэнні?"</string> <string name="inline_stop_button" msgid="2453460935438696090">"Спыніць апавяшчэнні"</string> <string name="inline_deliver_silently_button" msgid="2714314213321223286">"Дастаўляць бязгучна"</string> @@ -1021,9 +1021,9 @@ <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Рэжым чакання"</string> <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Паказваюцца ўверсе раздзела размоў"</string> - <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Паказваюць выяву профілю на экране блакіроўкі"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Паказваюць відарыс профілю на экране блакіроўкі"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Паказваюцца як рухомыя апавяшчэнні паверх праграм"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Не распаўсюджваюцца на рэжым \"Не турбаваць\""</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Паказваюцца ў рэжыме \"Не турбаваць\""</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Зразумела"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Акно-накладка з павелічэннем"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Акно павелічэння"</string> @@ -1039,6 +1039,13 @@ <item quantity="many">Дададзена <xliff:g id="NUMBER_1">%s</xliff:g> элементаў кіравання.</item> <item quantity="other">Дададзена <xliff:g id="NUMBER_1">%s</xliff:g> элемента кіравання.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Дададзена ў абранае, пазіцыя <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Выдалена з абранага"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"у абранае"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"выдаліць з абранага"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Перамясціць у пазіцыю <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Сродкі кіравання"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Выберыце элементы кіравання, да якіх вы хочаце мець доступ з меню сілкавання"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Каб змяніць парадак элементаў кіравання, утрымлівайце і перацягвайце іх"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 31e47da6baeb..1416e90543b7 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Добавени са <xliff:g id="NUMBER_1">%s</xliff:g> контроли.</item> <item quantity="one">Добавена е <xliff:g id="NUMBER_0">%s</xliff:g> контрола.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено като любимо – позиция <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не е означено като любимо"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"за означаване като любимо"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"за премахване на означаването като любимо"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Преместете на позиция <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Контроли"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Избиране на контроли, които да са достъпни в менюто за захранване"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задръжте и плъзнете, за да пренаредите контролите"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index 08826e46ab22..74cbfda3a3cc 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g>টি কন্ট্রোল যোগ করা হয়েছে।</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g>টি কন্ট্রোল যোগ করা হয়েছে।</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"পছন্দসই হিসেবে চিহ্নিত করেছেন, অবস্থান <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"পছন্দসই থেকে সরিয়ে দিয়েছেন"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"পছন্দসই"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"পছন্দসই থেকে সরান"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> অবস্থানে সরান"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"নিয়ন্ত্রণ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"যেসব কন্ট্রোল অ্যাক্সেস করতে চান সেগুলি পাওয়ার মেনু থেকে বেছে নিন"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"কন্ট্রোলগুলিকে আবার সাজানোর জন্য ধরে রেখে টেনে আনুন"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index 28a2930c522e..a062d1a3eee0 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -589,7 +589,7 @@ <string name="accessibility_volume_settings" msgid="1458961116951564784">"Postavke zvuka"</string> <string name="accessibility_volume_expand" msgid="7653070939304433603">"Proširi"</string> <string name="accessibility_volume_collapse" msgid="2746845391013829996">"Suzi"</string> - <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatski titluj medije"</string> + <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatski titlovi za medije"</string> <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Savjet u titlu"</string> <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Preklapanje titlova"</string> <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"omogući"</string> @@ -707,20 +707,20 @@ <string name="inline_minimize_button" msgid="1474436209299333445">"Minimiziraj"</string> <string name="inline_silent_button_silent" msgid="525243786649275816">"Nečujno"</string> <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Ostani u nečujnom načinu rada"</string> - <string name="inline_silent_button_alert" msgid="5705343216858250354">"Upozorenja"</string> + <string name="inline_silent_button_alert" msgid="5705343216858250354">"Zvučni"</string> <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Nastavi upozoravati"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obavještenja"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string> <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string> - <string name="notification_alert_title" msgid="7629202599338071971">"Upozorenja"</string> + <string name="notification_alert_title" msgid="7629202599338071971">"Zvučni"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Oblačić"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Pomaže vam da se koncentrirate bez zvuka ili vibracije."</string> - <string name="notification_channel_summary_default" msgid="3539949463907902037">"Privlači vašu pažnju pomoću zvuka ili vibracije."</string> + <string name="notification_channel_summary_default" msgid="3539949463907902037">"Privlači vam pažnju pomoću zvuka ili vibracije."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Privlači vašu pažnju pomoću zvuka ili vibracije. Razgovori iz oblačića u aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g> kao zadana opcija."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Privlači vašu pažnju pomoću plutajuće prečice do ovog sadržaja."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Prikazuje se na vrhu odjeljka za razgovor u vidu oblačića."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Postavke"</string> - <string name="notification_priority_title" msgid="2079708866333537093">"Prioritet"</string> + <string name="notification_priority_title" msgid="2079708866333537093">"Prioritetni"</string> <string name="no_shortcut" msgid="7176375126961212514">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> ne podržava postavke za određeni razgovor"</string> <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Nema nedavnih oblačića"</string> <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Nedavni i odbačeni oblačići će se pojaviti ovdje"</string> @@ -749,7 +749,7 @@ <string name="notification_conversation_favorite" msgid="1905240206975921907">"Važan razgovor"</string> <string name="notification_conversation_unfavorite" msgid="181383708304763807">"Nije važan razgovor"</string> <string name="notification_conversation_mute" msgid="268951550222925548">"Bez zvuka"</string> - <string name="notification_conversation_unmute" msgid="2692255619510896710">"Upozorenja"</string> + <string name="notification_conversation_unmute" msgid="2692255619510896710">"Zvučni"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Prikaži oblačić"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Ukloni oblačiće"</string> <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Dodaj na početni ekran"</string> @@ -1017,7 +1017,7 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Postavke da ažurirate navigiranje sistemom"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje mirovanja"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se iznad odjeljka za razgovor"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se na vrhu odjeljka za razgovor"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje sliku profila na zaključanom ekranu"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Izgleda kao plutajući oblačić iznad aplikacija"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Prekida način rada Ne ometaj"</string> @@ -1035,6 +1035,13 @@ <item quantity="few">Dodane su <xliff:g id="NUMBER_1">%s</xliff:g> kontrole.</item> <item quantity="other">Dodano je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u omiljeno, pozicija <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno iz omiljenog"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"dodate u omiljeno"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonite iz omiljenog"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Premjesti na poziciju <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Izaberite kontrole za pristup iz menija napajanja"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite i prevucite da preuredite kontrole"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 15cc8d39bb7a..12b82302633d 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -511,7 +511,7 @@ <string name="manage_notifications_text" msgid="6885645344647733116">"Gestiona"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"Entrants"</string> - <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacions silencioses"</string> + <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacions silenciades"</string> <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificacions d\'alerta"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Esborra totes les notificacions silencioses"</string> @@ -700,7 +700,7 @@ <string name="inline_block_button" msgid="479892866568378793">"Bloqueja"</string> <string name="inline_keep_button" msgid="299631874103662170">"Continua rebent"</string> <string name="inline_minimize_button" msgid="1474436209299333445">"Minimitza"</string> - <string name="inline_silent_button_silent" msgid="525243786649275816">"Silencioses"</string> + <string name="inline_silent_button_silent" msgid="525243786649275816">"Silenci"</string> <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Continua silenciant"</string> <string name="inline_silent_button_alert" msgid="5705343216858250354">"Alertes"</string> <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Continua avisant-me"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">S\'han afegit <xliff:g id="NUMBER_1">%s</xliff:g> controls.</item> <item quantity="one">S\'ha afegit <xliff:g id="NUMBER_0">%s</xliff:g> control.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Afegit als preferits, posició <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Suprimit dels preferits"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"afegir als preferits"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"suprimir dels preferits"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mou a la posició <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Selecciona els controls per accedir-hi des del menú d\'engegada"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén premut i arrossega per reorganitzar els controls"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index e3d9e384ed31..1d4d7c481440 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="other">Bylo přidáno <xliff:g id="NUMBER_1">%s</xliff:g> ovládacích prvků.</item> <item quantity="one">Byl přidán <xliff:g id="NUMBER_0">%s</xliff:g> ovládací prvek.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Přidáno do oblíbených na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odebráno z oblíbených"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"přidáte do oblíbených"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"odeberete z oblíbených"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Přesunout na pozici <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Ovládací prvky"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Vyberte ovládací prvky, které budou zobrazeny v nabídce vypínače"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Ovládací prvky můžete uspořádat podržením a přetažením"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 3d244cc60817..580aa7e1a5a6 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> styringselement er tilføjet.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> styringselementer er tilføjet.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Angivet som favorit. Position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet fra favoritter"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"markér som favorit"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"fjern fra favoritter"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Flyt til position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Betjeningselementer"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Vælg, hvilke indstillinger der skal være i menuen for afbryderknappen"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Flyt rundt på styringselementer ved at holde dem nede og trække"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 8ef83bdb47a1..b2f71a8c8fd3 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> Steuerelemente hinzugefügt.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> Steuerelement hinzugefügt.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Zu Favoriten hinzugefügt, Position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Aus Favoriten entfernt"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"Zum Hinzufügen zu Favoriten"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"Zum Entfernen aus Favoriten"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Auf Position <xliff:g id="NUMBER">%d</xliff:g> verschieben"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Steuerelemente"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Karten auswählen, auf die man über das Ein-/Aus-Menü zugreifen kann"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zum Verschieben von Steuerelementen halten und ziehen"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 1a930096c8fa..87b65f2ed3f7 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Προστέθηκαν <xliff:g id="NUMBER_1">%s</xliff:g> στοιχεία ελέγχου.</item> <item quantity="one">Προστέθηκε <xliff:g id="NUMBER_0">%s</xliff:g> στοιχείο ελέγχου.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Προστέθηκε στα αγαπημένα, στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Αφαιρέθηκε από τα αγαπημένα"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"αγαπημένο"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"μη αγαπημένο"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Μετακίνηση στη θέση <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Στοιχεία ελέγχου"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Επιλέξτε τα στοιχεία ελέγχου στα οποία θα έχετε πρόσβαση από το μενού λειτουργίας."</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Κρατήστε και σύρετε για αναδιάταξη των στοιχείων ελέγχου"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index b2a03d269443..d3b51b50b6f3 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favourite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavourite"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Choose controls to access from the power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index db9ed99b6607..90406fa32732 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favourite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavourite"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Choose controls to access from the power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index b2a03d269443..d3b51b50b6f3 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favourite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavourite"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Choose controls to access from the power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index b2a03d269443..d3b51b50b6f3 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favourited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavourited"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favourite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavourite"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Choose controls to access from the power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold and drag to rearrange controls"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 2b87b82e59b3..b29c5a2f2d85 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> control added.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removed"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Unfavorited"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favorite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"unfavorite"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Move to position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controls"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Choose controls to access from the power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold & drag to rearrange controls"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e7d6878dd186..64c4d6ef4e51 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Se agregaron <xliff:g id="NUMBER_1">%s</xliff:g> controles.</item> <item quantity="one">Se agregó <xliff:g id="NUMBER_0">%s</xliff:g> control.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Quitados"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está en favoritos en la posición <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"No está en favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"agregar a favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"quitar de favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover a la posición <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controles"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Elige los controles a los que quieres acceder desde el menú de encendido"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén presionado y arrastra para reorganizar los controles"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index d1f5198801b8..0e746b19c9c2 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Se han añadido <xliff:g id="NUMBER_1">%s</xliff:g> controles.</item> <item quantity="one">Se ha añadido <xliff:g id="NUMBER_0">%s</xliff:g> control.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Añadido a favoritos (posición <xliff:g id="NUMBER">%d</xliff:g>)"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Quitado de favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"añadir a favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"quitar de favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover a la posición <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controles"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Elige los controles a los que acceder desde el menú de encendido"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantén pulsado y arrastra un control para reubicarlo"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index c1b4b79d2089..0b44c0c3497a 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Lisati <xliff:g id="NUMBER_1">%s</xliff:g> juhtnuppu.</item> <item quantity="one">Lisati <xliff:g id="NUMBER_0">%s</xliff:g> juhtnupp.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisatud lemmikuks, positsioon <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eemaldatud lemmikute hulgast"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"lisa lemmikuks"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"eemalda lemmikute hulgast"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Teisalda asendisse <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Juhtnupud"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Valige toitemenüüs saadaolevad juhtelemendid"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Juhtnuppude ümberpaigutamiseks hoidke neid all ja lohistage"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 944b07b94227..a7d1c3945630 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -512,7 +512,7 @@ <string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"Jasotako azkenak"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Soinurik gabeko jakinarazpenak"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Soinua/Dar-dar egiten duten jakinarazpenak"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Jakinarazpen ohartarazleak"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Elkarrizketak"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Garbitu soinurik gabeko jakinarazpen guztiak"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Ez molestatzeko moduak pausatu egin ditu jakinarazpenak"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol-aukera gehitu dira.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol-aukera gehitu da.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>. gogokoa da"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Ez dago gogokoetan"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"gehitu gogokoetan"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"kendu gogokoetatik"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Eraman <xliff:g id="NUMBER">%d</xliff:g>garren postura"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrolatzeko aukerak"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Aukeratu itzaltzeko menutik atzitu nahi dituzun kontrolatzeko aukerak"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Kontrolatzeko aukerak antolatzeko, eduki itzazu sakatuta, eta arrastatu"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 64b3f8caef1f..75e460f06168 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> کنترل اضافه شده است.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> کنترل اضافه شده است.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"اضافهشده به موارد دلخواه، جایگاه <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"حذفشده از موارد دلخواه"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"افزودن به موارد دلخواه"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"حذف کردن از موارد دلخواه"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"انتقال به موقعیت <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"کنترلها"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"برای دسترسی از منوی روشن/خاموش، کنترلها را انتخاب کنید"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"برای تغییر دادن ترتیب کنترلها، آنها را نگه دارید و بکشید"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index a3c1e5e77bb2..d2c6e4778a28 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -713,7 +713,7 @@ <string name="notification_channel_summary_default" msgid="3539949463907902037">"Kiinnittää huomion äänellä tai värinällä"</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Kiinnittää huomion äänellä tai värinällä. Näistä keskusteluista (<xliff:g id="APP_NAME">%1$s</xliff:g>) syntyy oletuksena kuplia."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Kelluva sisällön pikakuvake säilyttää huomiosi"</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Näkyy keskusteluosion yläosassa kuplana"</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Näkyy keskustelukohdan yläosassa kuplana"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Asetukset"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Tärkeä"</string> <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei tue keskustelukohtaisia asetuksia"</string> @@ -1010,7 +1010,7 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Vaihda järjestelmän navigointitapaa asetuksista"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Virransäästötila"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Näkyy keskusteluosion yläosassa"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Näkyy keskustelukohdan yläosassa"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Profiilikuva näkyy lukitusnäytöllä"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Näkyy kelluvana kuplana sovellusten päällä"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Keskeyttää Älä häiritse ‑tilan"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> säädintä lisätty</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> säädin lisätty</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Lisätty suosikkeihin sijalle <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Poistettu suosikeista"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"suosikki"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"poista suosikeista"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Siirrä kohtaan <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Säätimet"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Valitse säätimet, joita käytetään virtavalikosta"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Järjestele säätimiä koskettamalla pitkään ja vetämällä"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index b34a038d7f34..c1a1efbd49a9 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -709,7 +709,7 @@ <string name="notification_silence_title" msgid="8608090968400832335">"Mode silencieux"</string> <string name="notification_alert_title" msgid="7629202599338071971">"Alertes"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Bulle"</string> - <string name="notification_channel_summary_low" msgid="7300447764759926720">"Vous aider à vous concentrer, sans son ni vibration."</string> + <string name="notification_channel_summary_low" msgid="7300447764759926720">"Vous aide à vous concentrer, sans son ni vibration."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Attire votre attention à l\'aide de sons et de vibrations."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Attire votre attention à l\'aide de sons et de vibrations. Conversations des bulles de <xliff:g id="APP_NAME">%1$s</xliff:g> par défaut."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Garde votre attention à l\'aide d\'un raccourci flottant vers ce contenu."</string> @@ -1010,7 +1010,7 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Veille"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aff. dans le haut de la section des conversations"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Afficher dans le haut de la section des conversations"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Afficher la photo de profil sur l\'écran verrouillé"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Sous forme de bulle flottante, par-dessus les applis"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrompre le mode Ne pas déranger"</string> @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> commande ajoutée.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> commandes ajoutées.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ajouter aux favoris"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"supprimer des favoris"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Déplacer l\'élément à la position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Commandes"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Sélectionnez les commandes auxquelles vous souhaitez accéder à partir du menu de l\'interrupteur"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Maintenez le doigt sur l\'écran, puis glissez-le pour réorganiser les commandes"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 1ec0411f7526..6bcea508ea10 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> controls added.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> commandes ajoutées.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ajouté aux favoris, en position <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Supprimé des favoris"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ajouter aux favoris"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"supprimer des favoris"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Déplacer l\'élément à la position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Commandes"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Sélectionnez les commandes auxquelles vous souhaitez accéder depuis le menu de démarrage"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Appuyer et faire glisser pour réorganiser les commandes"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 0095bcc6b127..c8eca6af21fc 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Engadíronse <xliff:g id="NUMBER_1">%s</xliff:g> controis.</item> <item quantity="one">Engadiuse <xliff:g id="NUMBER_0">%s</xliff:g> control.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Está entre os controis favoritos (posición: <xliff:g id="NUMBER">%d</xliff:g>)"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Non está entre os controis favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"engadir aos controis favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"quitar dos controis favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover á posición <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controis"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Escolle os controis para acceder desde o menú de acendido"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Para reorganizar os controis, mantenos premidos e arrástraos"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 6d2dec85b860..ca3d6587e964 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -32,7 +32,7 @@ <string name="invalid_charger" msgid="4370074072117767416">"USB મારફતે ચાર્જ કરી શકતા નથી. તમારા ઉપકરણ સાથે આવેલ ચાર્જરનો ઉપયોગ કરો."</string> <string name="invalid_charger_title" msgid="938685362320735167">"USB મારફતે ચાર્જ કરી શકતા નથી"</string> <string name="invalid_charger_text" msgid="2339310107232691577">"તમારા ઉપકરણ સાથે આવેલ ચાર્જરનો ઉપયોગ કરો"</string> - <string name="battery_low_why" msgid="2056750982959359863">"સેટિંગ્સ"</string> + <string name="battery_low_why" msgid="2056750982959359863">"સેટિંગ"</string> <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"બૅટરી સેવર ચાલુ કરીએ?"</string> <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"બૅટરી સેવર વિશે"</string> <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"ચાલુ કરો"</string> @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> નિયંત્રણ ઉમેર્યું.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> નિયંત્રણો ઉમેર્યા.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"મનપસંદમાં ઉમેર્યું, સ્થાન <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"મનપસંદમાંથી કાઢી નાખ્યું"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"મનપસંદમાં ઉમેરો"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"મનપસંદમાંથી કાઢી નાખો"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"સ્થાન <xliff:g id="NUMBER">%d</xliff:g> પર ખસેડો"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"નિયંત્રણો"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"પાવર મેનૂમાંથી ઍક્સેસ કરવા માટેના નિયંત્રણોને પસંદ કરો"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"નિયંત્રણોને ફરીથી ગોઠવવા માટે તેમને હોલ્ડ કરીને ખેંચો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index c7211f78d2a8..a568846f0cd2 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -1029,6 +1029,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> कंट्रोल जोड़ा गया.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> कंट्रोल जोड़े गए.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"पसंदीदा बनाया गया, क्रम संख्या <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"पसंदीदा से हटाया गया"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"पसंदीदा बनाएं"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"पसंदीदा से हटाएं"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"इसे <xliff:g id="NUMBER">%d</xliff:g> नंबर पर ले जाएं"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"कंट्राेल"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"पावर मेन्यू से ऐक्सेस करने के लिए कंट्रोल चुनें"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"कंट्रोल का क्रम फिर से बदलने के लिए उन्हें दबाकर रखें और खींचें"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 34f9b7a2294f..c914a7fe9aa0 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -1033,6 +1033,13 @@ <item quantity="few">Dodane su <xliff:g id="NUMBER_1">%s</xliff:g> kontrole.</item> <item quantity="other">Dodano je <xliff:g id="NUMBER_1">%s</xliff:g> kontrola.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u favorite"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano u favorite, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Uklonjeno iz favorita"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"dodali u favorite"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"uklonili iz favorita"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Premjestite na položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrole"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Odaberite kontrole kojima želite pristupati iz izbornika napajanja"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Zadržite i povucite da biste promijenili raspored kontrola"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 45462d4cd3f7..de51b2465831 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> vezérlő hozzáadva.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> vezérlő hozzáadva.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Hozzáadva a kedvencekhez <xliff:g id="NUMBER">%d</xliff:g>. helyen"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Eltávolítva a kedvencek közül"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"kedvencekhez adás"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"eltávolítás a kedvencek közül"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Áthelyezés a következő pozícióba: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Vezérlők"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"A bekapcsológomb menüjéből hozzáférhető vezérlők kiválasztása"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tartsa lenyomva, és húzza a vezérlők átrendezéséhez"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 33cf2a3280f0..bb0ac29284b0 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -713,7 +713,7 @@ <string name="notification_channel_summary_default" msgid="3539949463907902037">"Ծանուցումները գալիս են ձայնով կամ թրթռոցով։"</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Ծանուցումները գալիս են ձայնով կամ թրթռոցով։ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի զրույցներն ըստ կանխադրման հայտնվում են ամպիկների տեսքով։"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Լողացող դյուրանցման միջոցով ձեր ուշադրությունն է գրավում բովանդակության նկատմամբ"</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Ցուցադրվում է «Խոսակցություններ» բաժնում և հայտնվում է ամպիկի տեսքով։"</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Ցուցադրվում է զրույցների ցանկի վերևում և հայտնվում է ամպիկի տեսքով։"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Կարգավորումներ"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Կարևոր"</string> <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը չի աջակցում զրույցի կարգավորումները"</string> @@ -740,9 +740,9 @@ <string name="notification_app_settings" msgid="8963648463858039377">"Կարգավորել"</string> <string name="notification_done" msgid="6215117625922713976">"Պատրաստ է"</string> <string name="inline_undo" msgid="9026953267645116526">"Հետարկել"</string> - <string name="demote" msgid="6225813324237153980">"Նշել այս ծանուցումը որպես ոչ խոսակցություն"</string> - <string name="notification_conversation_favorite" msgid="1905240206975921907">"Կարևոր խոսակցություն"</string> - <string name="notification_conversation_unfavorite" msgid="181383708304763807">"Ոչ կարևոր խոսակցություն"</string> + <string name="demote" msgid="6225813324237153980">"Նշել այս ծանուցումը որպես ոչ զրույց"</string> + <string name="notification_conversation_favorite" msgid="1905240206975921907">"Կարևոր զրույց"</string> + <string name="notification_conversation_unfavorite" msgid="181383708304763807">"Ոչ կարևոր զրույց"</string> <string name="notification_conversation_mute" msgid="268951550222925548">"Լռեցված"</string> <string name="notification_conversation_unmute" msgid="2692255619510896710">"Միացնել ծանուցումների ձայնը"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Ցուցադրել ամպիկը"</string> @@ -1000,7 +1000,7 @@ <string name="bubble_accessibility_action_move_bottom_left" msgid="6339015902495504715">"Տեղափոխել ներքև՝ ձախ"</string> <string name="bubble_accessibility_action_move_bottom_right" msgid="7471571700628346212">"Տեղափոխել ներքև՝ աջ"</string> <string name="bubble_dismiss_text" msgid="7071770411580452911">"Փակել"</string> - <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Խոսակցությունը չցուցադրել ամպիկի տեսքով"</string> + <string name="bubbles_dont_bubble_conversation" msgid="1033040343437428822">"Զրույցը չցուցադրել ամպիկի տեսքով"</string> <string name="bubbles_user_education_title" msgid="5547017089271445797">"Զրուցել ամպիկների միջոցով"</string> <string name="bubbles_user_education_description" msgid="1160281719576715211">"Նոր խոսակցությունները կհայտնվեն լողացող պատկերակների կամ ամպիկների տեսքով։ Հպեք՝ ամպիկը բացելու համար։ Քաշեք՝ այն տեղափոխելու համար։"</string> <string name="bubbles_user_education_manage_title" msgid="2848511858160342320">"Ամպիկների կարգավորումներ"</string> @@ -1010,10 +1010,10 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Սպասման ռեժիմ"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Ցուցադրվում են «Խոսակցություններ» բաժնի վերևում"</string> - <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ցուցադրում են պրոֆիլի նկարը կողպէկրանին"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Ցուցադրել զրույցների ցանկի վերևում"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ցուցադրել պրոֆիլի նկարը կողպէկրանին"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Հայտնվում են որպես լողացող ամպիկ հավելվածների վրայից"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ընդհատում են «Չանհանգստացնել» ռեժիմը"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ընդհատել «Չանհանգստացնել» ռեժիմը"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Եղավ"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Խոշորացման պատուհանի վրադրում"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Խոշորացման պատուհան"</string> @@ -1027,6 +1027,13 @@ <item quantity="one">Ավելացվեց կառավարման <xliff:g id="NUMBER_1">%s</xliff:g> տարր։</item> <item quantity="other">Ավելացվեց կառավարման <xliff:g id="NUMBER_1">%s</xliff:g> տարր։</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ավելացված է ընտրանիում, դիրքը՝ <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Հեռացված է ընտրանուց"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ընտրանիում ավելացնելու համար"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ընտրանուց հեռացնելու համար"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Տեղափոխել դիրք <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Կառավարման տարրեր"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Ընտրեք կառավարման տարրերը՝ դրանք սնուցման ընտրացանկից բացելու համար"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Պահեք և քաշեք՝ կառավարման տարրերը վերադասավորելու համար"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 35aabc73fa93..abaa94160d08 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol ditambahkan.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol ditambahkan.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Difavoritkan, posisi <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Batal difavoritkan"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favorit"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"batal favoritkan"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Pindah ke posisi <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrol"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Pilih kontrol yang akan diakses dari menu daya"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan & tarik untuk mengatur ulang kontrol"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 52d63b0eb5e0..c289e95d0903 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> stýringu bætt við.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> stýringum bætt við.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Eftirlæti, staða <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjarlægt úr eftirlæti"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"setja í eftirlæti"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"fjarlægja úr eftirlæti"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Færa í stöðu <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Stýringar"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Veldu hvaða stýringar birtast í aflrofavalmyndinni"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Haltu og dragðu til að endurraða stýringum"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 1a71d91afb65..35a65dd3c92c 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -709,7 +709,7 @@ <string name="notification_silence_title" msgid="8608090968400832335">"Modalità silenziosa"</string> <string name="notification_alert_title" msgid="7629202599338071971">"Avvisi"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Fumetto"</string> - <string name="notification_channel_summary_low" msgid="7300447764759926720">"Favorisce la tua concentrazione grazie all\'assenza di suono o vibrazione."</string> + <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ti aiuta a non perdere la concentrazione grazie all\'assenza di suono o vibrazione."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Richiama la tua attenzione con suono o vibrazione."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Richiama la tua attenzione con suono o vibrazione. Conversazioni dalla bolla <xliff:g id="APP_NAME">%1$s</xliff:g> per impostazione predefinita."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantiene la tua attenzione con una scorciatoia mobile a questi contenuti."</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controlli aggiunti.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> controllo aggiunto.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Rimosso"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Aggiunto ai preferiti"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Preferito, posizione <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Rimosso dai preferiti"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"aggiungere l\'elemento ai preferiti"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"rimuovere l\'elemento dai preferiti"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Sposta nella posizione <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controlli"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Seleziona i controlli a cui accedere dal menu di accensione"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tieni premuto e trascina per riordinare i controlli"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 121f9bb9f18c..67a7a9317170 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="other">נוספו <xliff:g id="NUMBER_1">%s</xliff:g> פקדים.</item> <item quantity="one">נוסף פקד אחד (<xliff:g id="NUMBER_0">%s</xliff:g>).</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"הוסר"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כהעדפה"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"סומן כהעדפה, במיקום <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"הוסר מהמועדפים"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"להוסיף למועדפים"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"להוסיף למועדפים"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"העברה למיקום <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"פקדים"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"יש לבחור פקדים לגישה מתפריט ההפעלה"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"יש ללחוץ לחיצה ארוכה ולגרור כדי לארגן מחדש את הפקדים"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 42ecb6403665..59e1b1744e7f 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> 件のコントロールを追加しました。</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> 件のコントロールを追加しました。</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"削除済み"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"お気に入りに追加済み"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"お気に入りに追加済み、位置: <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"お気に入りから削除済み"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"お気に入りに追加"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"お気に入りから削除"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ポジション <xliff:g id="NUMBER">%d</xliff:g> に移動"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"コントロール"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"電源ボタン メニューからアクセスするコントロールを選択する"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"コントロールを並べ替えるには長押ししてドラッグします"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 36580b7e3fee..193a513f3fa5 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">დაემატა <xliff:g id="NUMBER_1">%s</xliff:g> მართვის საშუალება.</item> <item quantity="one">დაემატა <xliff:g id="NUMBER_0">%s</xliff:g> მართვის საშუალება.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"რჩეულებშია, პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"რჩეულებიდან ამოღებულია"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"რჩეული"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"რჩეულებიდან ამოღება"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"გადატანა პოზიციაზე <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"მართვის საშუალებები"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"აირჩიეთ მართვის საშუალებები ელკვების მენიუდან"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"მართვის საშუალებების გადაწყობა შეგიძლიათ მათი ჩავლებით გადატანით"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 53ead8e5c77c..e0117fe78826 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> басқару элементі енгізілді.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> басқару элементі енгізілді.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Таңдаулыларға қосылды, <xliff:g id="NUMBER">%d</xliff:g>-позиция"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Таңдаулылардан алып тасталды"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"таңдаулылар"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"таңдаулылардан алып тастау"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> позициясына жылжыту"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Басқару элементтері"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"\"Қуат\" мәзірінен пайдалануға болатын басқару элементтерін таңдаңыз."</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Басқару элементтерінің ретін өзгерту үшін оларды басып тұрып сүйреңіз."</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index a33b9f536ead..00b455b819d6 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -709,7 +709,7 @@ <string name="notification_silence_title" msgid="8608090968400832335">"ស្ងាត់"</string> <string name="notification_alert_title" msgid="7629202599338071971">"បញ្ចេញសំឡេង"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"ពពុះ"</string> - <string name="notification_channel_summary_low" msgid="7300447764759926720">"ជួយឱ្យអ្នកផ្តោតអារម្មណ៍ ដោយមិនឮសំឡេង ឬការញ័រ។"</string> + <string name="notification_channel_summary_low" msgid="7300447764759926720">"ជួយឱ្យអ្នកផ្តោតអារម្មណ៍ ដោយមិនឮសំឡេង ឬញ័រ។"</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"ធ្វើឱ្យអ្នកចាប់អារម្មណ៍តាមរយៈសំឡេង ឬការញ័រ។"</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ធ្វើឱ្យអ្នកចាប់អារម្មណ៍តាមរយៈសំឡេង ឬការញ័រ។ ការសន្ទនាពីពពុះ <xliff:g id="APP_NAME">%1$s</xliff:g> តាមលំនាំដើម។"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ធ្វើឱ្យអ្នកចាប់អារម្មណ៍ដោយប្រើផ្លូវកាត់អណ្ដែតសម្រាប់ខ្លឹមសារនេះ។"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">បានបញ្ចូលការគ្រប់គ្រង <xliff:g id="NUMBER_1">%s</xliff:g>។</item> <item quantity="one">បានបញ្ចូលការគ្រប់គ្រង <xliff:g id="NUMBER_0">%s</xliff:g>។</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជាសំណព្វ"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"បានដាក់ជាសំណព្វ ទីតាំងទី <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"បានដកចេញពីសំណព្វ"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ដាក់ជាសំណព្វ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ដកចេញពីសំណព្វ"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ផ្លាស់ទីទៅតាំងទី <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ការគ្រប់គ្រង"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ជ្រើសរើសការគ្រប់គ្រង ដើម្បីចូលប្រើពីម៉ឺនុយថាមពល"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ចុចឱ្យជាប់ រួចអូសដើម្បីរៀបចំការគ្រប់គ្រងឡើងវិញ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index cca8c6b76dd2..d2554c1dfa4d 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ಮೆಚ್ಚಲಾಗಿರುವುದು, ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ಮೆಚ್ಚಿನದಲ್ಲದ್ದು"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ಮೆಚ್ಚಿನ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ಮೆಚ್ಚಿನದಲ್ಲದ್ದು"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ಸ್ಥಾನ <xliff:g id="NUMBER">%d</xliff:g> ಕ್ಕೆ ಸರಿಸಿ"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ನಿಯಂತ್ರಣಗಳು"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ಪವರ್ ಮೆನುವಿನಿಂದ ಪ್ರವೇಶಿಸಲು ನಿಯಂತ್ರಣಗಳನ್ನು ಆರಿಸಿ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ನಿಯಂತ್ರಣಗಳನ್ನು ಮರುಹೊಂದಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಮತ್ತು ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 60ecdb7357c2..58433aa85076 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -1013,7 +1013,7 @@ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"대화 섹션의 상단에 표시"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"잠금 화면에서 프로필 사진 표시"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"앱 상단에서 플로팅 대화창으로 표시"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"방해 금지 모드 제외"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"방해 금지 모드 무시"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"확인"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"확대 오버레이 창"</string> <string name="magnification_window_title" msgid="4863914360847258333">"확대 창"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">제어 기능 <xliff:g id="NUMBER_1">%s</xliff:g>개가 추가되었습니다.</item> <item quantity="one">제어 기능 <xliff:g id="NUMBER_0">%s</xliff:g>개가 추가되었습니다.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"즐겨찾기에 추가됨, 위치 <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"즐겨찾기에서 삭제됨"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"즐겨찾기"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"즐겨찾기에서 삭제"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"다음 위치로 이동: <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"제어"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"전원 메뉴에서 액세스할 컨트롤을 선택합니다."</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"길게 누르고 드래그하여 컨트롤 재정렬"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index 6893e8f9bc5d..88fa00727df7 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> көзөмөл кошулду.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> көзөмөл кошулду.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Сүйүктүүлөргө <xliff:g id="NUMBER">%d</xliff:g>-позицияга кошулду"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Сүйүктүүлөрдөн чыгарылды"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"сүйүктүүлөргө кошуу"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"сүйүктүүлөрдөн чыгаруу"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>-позицияга жылдыруу"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Башкаруу элементтери"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Күйгүзүү/өчүрүү баскычынын менюсу үчүн көзөмөлдөрдү тандаңыз"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Башкаруу элементтеринин иретин өзгөртүү үчүн кармап туруп, сүйрөңүз"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 2514b3eb09dc..305d678db70a 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -715,7 +715,7 @@ <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ເອົາໃຈໃສ່ທາງລັດແບບລອຍໄປຫາເນື້ອຫານີ້."</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"ສະແດງຢູ່ເທິງສຸດຂອງພາກສ່ວນການສົນທະນາ ແລະ ສະແດງເປັນຟອງ."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"ຕັ້ງຄ່າ"</string> - <string name="notification_priority_title" msgid="2079708866333537093">"ຄວາມສຳຄັນ"</string> + <string name="notification_priority_title" msgid="2079708866333537093">"ສຳຄັນ"</string> <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ຮອງຮັບການຕັ້ງຄ່າສະເພາະຂອງການສົນທະນາ"</string> <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"ບໍ່ມີຟອງຫຼ້າສຸດ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"ຟອງຫຼ້າສຸດ ແລະ ຟອງທີ່ປິດໄປຈະປາກົດຢູ່ບ່ອນນີ້"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">ເພີ່ມ <xliff:g id="NUMBER_1">%s</xliff:g> ການຄວບຄຸມແລ້ວ.</item> <item quantity="one">ເພີ່ມ <xliff:g id="NUMBER_0">%s</xliff:g> ການຄວບຄຸມແລ້ວ.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ, ຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ຍົກເລີກລາຍການທີ່ມັກແລ້ວ"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ເພີ່ມລາຍການທີ່ມັກ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ຍົກເລີກລາຍການທີ່ມັກ"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ຍ້າຍໄປຕຳແໜ່ງ <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ການຄວບຄຸມ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ເລືອກການຄວບຄຸມເພື່ອເຂົ້າເຖິງຈາກເມນູເປີດປິດ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ກົດຄ້າງໄວ້ເພື່ອຈັດຮຽງການຄວບຄຸມຄືນໃໝ່"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 4f016d33fa2e..7c31473e913a 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="many">Pridėta <xliff:g id="NUMBER_1">%s</xliff:g> valdiklio.</item> <item quantity="other">Pridėta <xliff:g id="NUMBER_1">%s</xliff:g> valdiklių.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Pašalinta"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Įtraukta į mėgstamiausius"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Įtraukta į mėgstamiausius, padėtis: <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Pašalinta iš mėgstamiausių"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"įtraukti į mėgstamiausius"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"pašalinti iš mėgstamiausių"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Perkelti į <xliff:g id="NUMBER">%d</xliff:g> padėtį"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Valdikliai"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Pasirinkite valdiklius, kuriuos norite pasiekti įjungimo meniu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Norėdami pertvarkyti valdiklius, vilkite laikydami nuspaudę"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 5cc696c98a7e..211e3638a116 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -1033,6 +1033,13 @@ <item quantity="one">Pievienota <xliff:g id="NUMBER_1">%s</xliff:g> vadīkla.</item> <item quantity="other">Pievienotas <xliff:g id="NUMBER_1">%s</xliff:g> vadīklas.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pievienota izlasei, <xliff:g id="NUMBER">%d</xliff:g>. pozīcija"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Noņemta no izlases"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"pievienotu izlasei"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"noņemtu no izlases"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Pārvietot uz <xliff:g id="NUMBER">%d</xliff:g>. pozīciju"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Vadīklas"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Izvēlieties vadīklas, kurām piekļūt no barošanas izvēlnes"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Lai pārkārtotu vadīklas, turiet un velciet tās"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 64f614f09b9a..45e37d68b7bd 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one">Додадена е <xliff:g id="NUMBER_1">%s</xliff:g> контрола.</item> <item quantity="other">Додадени се <xliff:g id="NUMBER_1">%s</xliff:g> контроли.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Отстранета"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Омилена"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Омилена, позиција <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Неомилена"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"означите како омилена"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"означите како неомилена"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Преместете на позиција <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Контроли"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Изберете ги контролите до кои ќе пристапувате од менито за вклучување"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржете и влечете за да ги преуредите контролите"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index bee7e919947f..63aa40e97b8d 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> നിയന്ത്രണങ്ങൾ ചേർത്തു.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> നിയന്ത്രണം ചേർത്തു.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്തു"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"പ്രിയപ്പെട്ടതാക്കി, സ്ഥാനം <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"പ്രിയപ്പെട്ടതല്ലാതാക്കി"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"പ്രിയപ്പെട്ടതാക്കുക"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"പ്രിയപ്പെട്ടതല്ലാതാക്കുക"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>-ാം സ്ഥാനത്തേയ്ക്ക് നീക്കുക"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"നിയന്ത്രണങ്ങൾ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"പവർ മെനുവിൽ നിന്ന് ആക്സസ് ചെയ്യേണ്ട നിയന്ത്രണങ്ങൾ തിരഞ്ഞെടുക്കുക"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"നിയന്ത്രണങ്ങൾ പുനഃക്രമീകരിക്കാൻ പിടിച്ച് വലിച്ചിടുക"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index 9e915e0443e4..a007553a5846 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> хяналтыг нэмлээ.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> хяналтыг нэмлээ.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Хассан"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>-р байршилд дуртай гэж тэмдэглэсэн"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Дургүй гэж тэмдэглэсэн"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"дуртай гэж тэмдэглэх"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"дургүй гэж тэмдэглэх"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>-р байрлал руу зөөх"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Хяналт"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Тэжээлийн цэсээс хандах хяналтуудыг сонгоно уу"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Хяналтуудыг дахин засварлахын тулд дараад чирнэ үү"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index d0730c099198..5cf0ebb3a606 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> नियंत्रणे जोडली.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियंत्रण जोडले.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"आवडले, स्थान <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"नावडले"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"आवडते"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"नावडते"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> स्थानावर हलवा"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"नियंत्रणे"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"पॉवर मेनूमधून अॅक्सेस करण्यासाठी नियंत्रणे निवडा"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियंत्रणांची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index 94b5ad356f89..44bd1a6a425e 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -512,7 +512,7 @@ <string name="manage_notifications_history_text" msgid="57055985396576230">"Sejarah"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"Masuk"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Pemberitahuan senyap"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Pemberitahuan memaklumi"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Pemberitahuan makluman"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Kosongkan semua pemberitahuan senyap"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Pemberitahuan dijeda oleh Jangan Ganggu"</string> @@ -702,12 +702,12 @@ <string name="inline_minimize_button" msgid="1474436209299333445">"Minimumkan"</string> <string name="inline_silent_button_silent" msgid="525243786649275816">"Senyap"</string> <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Kekal senyap"</string> - <string name="inline_silent_button_alert" msgid="5705343216858250354">"Memaklumi"</string> + <string name="inline_silent_button_alert" msgid="5705343216858250354">"Pemakluman"</string> <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Teruskan memberikan makluman"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Matikan pemberitahuan"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Terus tunjukkan pemberitahuan daripada apl ini?"</string> <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string> - <string name="notification_alert_title" msgid="7629202599338071971">"Memaklumi"</string> + <string name="notification_alert_title" msgid="7629202599338071971">"Pemakluman"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Gelembung"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Membantu anda fokus tanpa bunyi atau getaran."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Menarik perhatian anda dengan bunyi atau getaran."</string> @@ -744,7 +744,7 @@ <string name="notification_conversation_favorite" msgid="1905240206975921907">"Perbualan penting"</string> <string name="notification_conversation_unfavorite" msgid="181383708304763807">"Bukan perbualan penting"</string> <string name="notification_conversation_mute" msgid="268951550222925548">"Disenyapkan"</string> - <string name="notification_conversation_unmute" msgid="2692255619510896710">"Memaklumi"</string> + <string name="notification_conversation_unmute" msgid="2692255619510896710">"Pemakluman"</string> <string name="notification_conversation_bubble" msgid="2242180995373949022">"Tunjukkan gelembung"</string> <string name="notification_conversation_unbubble" msgid="6908427185031099868">"Alih keluar gelembung"</string> <string name="notification_conversation_home_screen" msgid="8347136037958438935">"Tambahkan pada skrin utama"</string> @@ -1013,7 +1013,7 @@ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Tunjukkan di atas bahagian perbualan"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Tunjukkan gambar profil pada skrin kunci"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Dipaparkan sebagai gelembung terapung di atas apl"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ganggu Ciri Jangan Ganggu"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ganggu ciri Jangan Ganggu"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Tetingkap Tindanan Pembesaran"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Tetingkap Pembesaran"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kawalan ditambah.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kawalan ditambah.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Digemari, kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Dinyahgemari"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"gemari"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"nyahgemari"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Alih ke kedudukan <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kawalan"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Pilih kawalan untuk diakses daripada menu kuasa"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Tahan & seret untuk mengatur semula kawalan"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 58160fc22825..02eae37c9067 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -511,8 +511,8 @@ <string name="manage_notifications_text" msgid="6885645344647733116">"စီမံရန်"</string> <string name="manage_notifications_history_text" msgid="57055985396576230">"မှတ်တမ်း"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"အဝင်"</string> - <string name="notification_section_header_gentle" msgid="3044910806569985386">"အကြောင်းကြားချက်များကို အသံတိတ်ခြင်း"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"အကြောင်းကြားချက်များကို သတိပေးခြင်း"</string> + <string name="notification_section_header_gentle" msgid="3044910806569985386">"အသံမပြုသည့် အကြောင်းကြားချက်များ"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"သတိပေးသည့် အကြောင်းကြားချက်များ"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"အသံတိတ် အကြောင်းကြားချက်များအားလုံးကို ရှင်းလင်းရန်"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"အကြောင်းကြားချက်များကို \'မနှောင့်ယှက်ရ\' က ခေတ္တရပ်ထားသည်"</string> @@ -1010,7 +1010,7 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"အသင့်အနေအထား"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"စကားဝိုင်းအပိုင်း၏ ထိပ်တွင်ပြရန်"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"စကားဝိုင်းကဏ္ဍ၏ အပေါ်ဘက်တွင်ပြရန်"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံကို ပြရန်"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"အက်ပ်အပေါ်တွင် မျောနေသောပူဖောင်းကွက်အဖြစ် ပေါ်မည်"</string> <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'မနှောင့်ယှက်ရ\' ကို ကြားဖြတ်ခြင်း"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">ခလုတ် <xliff:g id="NUMBER_1">%s</xliff:g> ခု ထည့်လိုက်သည်။</item> <item quantity="one">ခလုတ် <xliff:g id="NUMBER_0">%s</xliff:g> ခု ထည့်လိုက်သည်။</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်၊ အဆင့် <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"အကြိုက်ဆုံးမှ ဖယ်ရှားထားသည်"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"အကြိုက်ဆုံးတွင် ထည့်ရန်"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"အကြိုက်ဆုံးမှ ဖယ်ရှားရန်"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"အနေအထား <xliff:g id="NUMBER">%d</xliff:g> သို့ ရွှေ့ရန်"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ထိန်းချုပ်မှုများ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ဖွင့်ပိတ်မီနူးမှ သုံးရန် ထိန်းချုပ်မှုများ ရွေးပါ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ထိန်းချုပ်မှုများ ပြန်စီစဉ်ရန် ဖိပြီးဆွဲပါ"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 0c21879d132f..e935425c899f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroller er lagt til.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontroll er lagt til.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favoritt, posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Fjernet som favoritt"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"merke som favoritt"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"fjerne som favoritt"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Flytt til posisjon <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontroller"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Velg kontroller som er tilgjengelige fra av/på-menyen"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Hold og dra for å flytte kontroller"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 6a0423c7fa30..a4b271ba3027 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> वटा नियन्त्र थपियो।</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> नियन्त्र थपियो</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"मन पराइएका कुराहरूको <xliff:g id="NUMBER">%d</xliff:g> औँ स्थानमा"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"मन पर्ने कुराहरूको सूचीमा नराखिएको"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"मन पर्ने कुराहरूको सूचीमा राख्नुहोस्"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"मन पर्ने कुराहरूको सूचीमा नराख्नुहोस्"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>ले निर्देश गर्ने ठाउँमा सार्नुहोस्"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"नियन्त्रणहरू"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"पावर मेनुबाट प्रयोग गर्न चाहेका नियन्त्रण सुविधाहरू छान्नुहोस्"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"नियन्त्रणहरूको क्रम मिलाउन तिनलाई थिचेर ड्र्याग गर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 419fa3eae472..94c72ffc8e6c 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> bedieningselementen toegevoegd.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> bedieningselement toegevoegd.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Gemarkeerd als favoriet, positie <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Verwijderd als favoriet"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"als favoriet markeren"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"als favoriet verwijderen"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Verplaatsen naar positie <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Bedieningselementen"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Kies bedieningselementen die je vanaf het aan/uit-menu wilt kunnen gebruiken"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Houd vast en sleep om de bedieningselementen opnieuw in te delen"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index ef753b8c097d..604e93f1a7a8 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g>ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g>ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ପସନ୍ଦ କରାଯାଇଛି, ସ୍ଥିତି <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ନାପସନ୍ଦ କରାଯାଇଛି"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ପସନ୍ଦ କରନ୍ତୁ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ନାପସନ୍ଦ କରନ୍ତୁ"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> ସ୍ଥିତିକୁ ମୁଭ୍ କରନ୍ତୁ"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ପାୱାର ମେନୁରୁ ଆକ୍ସେସ୍ କରିବାକୁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ବାଛନ୍ତୁ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ପୁଣି ସଜାଇବାକୁ ସେଗୁଡ଼ିକୁ ଧରି ଟାଣନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index b9db02a48180..c5a9b3529ae2 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ, ਸਥਾਨ <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ਮਨਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਇਆ ਗਿਆ"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ਮਨਪਸੰਦ ਵਿੱਚੋਂ ਹਟਾਓ"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> ਸਥਾਨ \'ਤੇ ਲਿਜਾਓ"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"ਕੰਟਰੋਲ"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"ਪਹੁੰਚ ਕਰਨ ਲਈ ਪਾਵਰ ਮੀਨੂ ਤੋਂ ਕੰਟਰੋਲ ਚੁਣੋ"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"ਕੰਟਰੋਲਾਂ ਨੂੰ ਮੁੜ-ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਘਸੀਟੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 19d9a6e2bc0c..350bdd907f91 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="other">Dodano <xliff:g id="NUMBER_1">%s</xliff:g> elementu sterującego</item> <item quantity="one">Dodano <xliff:g id="NUMBER_0">%s</xliff:g> element sterujący</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano do ulubionych, pozycja <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Usunięto z ulubionych"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"dodać do ulubionych"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"usunąć z ulubionych"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Przenieś w położenie <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Elementy sterujące"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Wybierz elementy sterujące dostępne w menu zasilania"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Przytrzymaj i przeciągnij, aby przestawić elementy sterujące"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index d63d62377bb6..af6d755fb177 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -706,7 +706,7 @@ <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Continuar alertando"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuar mostrando notificações desse app?"</string> - <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosa"</string> + <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string> <string name="notification_alert_title" msgid="7629202599338071971">"Alertar"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ajuda você a manter o foco sem som ou vibração."</string> @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> controle adicionado.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controles adicionados.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"adicionar aos favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"remover dos favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover para a posição <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controles"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Escolha os controles para acessar pelo menu do botão liga/desliga"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantenha a tela pressionada e arraste para reorganizar os controles"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 2b34ac3c0860..17853c46f184 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -709,11 +709,11 @@ <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string> <string name="notification_alert_title" msgid="7629202599338071971">"Alertar"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Balão"</string> - <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ajuda-o a focar-se sem som ou vibração."</string> - <string name="notification_channel_summary_default" msgid="3539949463907902037">"Chama a sua atenção com som ou vibração."</string> + <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ajuda-o a concentrar-se sem som ou vibração"</string> + <string name="notification_channel_summary_default" msgid="3539949463907902037">"Chama a sua atenção com som ou vibração"</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Chama a sua atenção com som ou vibração. As conversas da app <xliff:g id="APP_NAME">%1$s</xliff:g> aparecem como um balão por predefinição."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Mantém a sua atenção com um atalho flutuante para este conteúdo."</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Aparece na parte superior da secção de conversas e surge como um balão."</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Aparece na parte superior da secção de conversas e surge como um balão"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Definições"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Prioridade"</string> <string name="no_shortcut" msgid="7176375126961212514">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> não suporta definições específicas de conversas."</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controlos adicionados.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> controlo adicionado.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"adicionar aos favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"remover dos favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover para a posição <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controlos"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Escolha os controlos a que pretende aceder a partir do menu ligar/desligar."</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Toque sem soltar e arraste para reorganizar os controlos."</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index d63d62377bb6..af6d755fb177 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -706,7 +706,7 @@ <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Continuar alertando"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Continuar mostrando notificações desse app?"</string> - <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosa"</string> + <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string> <string name="notification_alert_title" msgid="7629202599338071971">"Alertar"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Bolha"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Ajuda você a manter o foco sem som ou vibração."</string> @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> controle adicionado.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> controles adicionados.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Removido"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionado como favorito (posição <xliff:g id="NUMBER">%d</xliff:g>)"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Removido dos favoritos"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"adicionar aos favoritos"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"remover dos favoritos"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mover para a posição <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Controles"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Escolha os controles para acessar pelo menu do botão liga/desliga"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mantenha a tela pressionada e arraste para reorganizar os controles"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index ce8b05f47a8e..249122109d77 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -1033,6 +1033,13 @@ <item quantity="other">S-au adăugat <xliff:g id="NUMBER_1">%s</xliff:g> de comenzi.</item> <item quantity="one">S-a adăugat <xliff:g id="NUMBER_0">%s</xliff:g> comandă.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Marcată ca preferată, poziția <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"S-a anulat marcarea ca preferată"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"marcați ca preferată"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"anulați marcarea ca preferată"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Mutați pe poziția <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Comenzi"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Alegeți comenzile de accesat din meniul de alimentare"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Țineți apăsat și trageți pentru a rearanja comenzile"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 38d8874e02ea..b752fc452585 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -719,7 +719,7 @@ <string name="notification_channel_summary_default" msgid="3539949463907902037">"Уведомления приходят со звуком или вибрацией"</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Уведомления приходят со звуком или вибрацией. Разговоры из приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" по умолчанию появляются в виде всплывающего чата."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Привлекает ваше внимание к контенту с помощью плавающего ярлыка"</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Появляется в верхней части списка разговоров и в виде всплывающего чата."</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Появляется в верхней части списка разговоров и в виде всплывающего чата"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Настройки"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Приоритет"</string> <string name="no_shortcut" msgid="7176375126961212514">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" не поддерживает настройки разговора."</string> @@ -1039,6 +1039,13 @@ <item quantity="many">Добавлено <xliff:g id="NUMBER_1">%s</xliff:g> элементов управления.</item> <item quantity="other">Добавлено <xliff:g id="NUMBER_1">%s</xliff:g> элемента управления.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Удалено"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Добавлено в избранное на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Не добавлено в избранное"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"добавить в избранное"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"удалить из избранного"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Переместить на позицию <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Элементы управления"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Выберите элементы управления, которые будут доступны в меню кнопки питания."</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Чтобы изменить порядок элементов управления, перетащите их"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index abe2dc26b81e..7c4a13aaba01 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one">පාලන <xliff:g id="NUMBER_1">%s</xliff:g>ක් එක් කරන ලදී.</item> <item quantity="other">පාලන <xliff:g id="NUMBER_1">%s</xliff:g>ක් එක් කරන ලදී.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්රියතම කළා"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ප්රියතම කළා, තත්ත්ව <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ප්රියතම වෙතින් ඉවත් කළා"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ප්රියතම කරන්න"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ප්රියතම වෙතින් ඉවත් කරන්න"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ස්ථාන <xliff:g id="NUMBER">%d</xliff:g> වෙත ගෙන යන්න"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"පාලන"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"බල මෙනුවෙන් ප්රවේශ වීමට පාලන තෝරා ගන්න"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"පාලන නැවත පිළියෙළ කිරීමට අල්ලාගෙන සිට අදින්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index f9535fa55a26..015da6895a34 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -592,7 +592,7 @@ <string name="accessibility_volume_settings" msgid="1458961116951564784">"Nastavenia zvuku"</string> <string name="accessibility_volume_expand" msgid="7653070939304433603">"Rozbaliť"</string> <string name="accessibility_volume_collapse" msgid="2746845391013829996">"Zbaliť"</string> - <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automaticky pridávať titulky k médiám"</string> + <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatické titulkovanie médií"</string> <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Zavrieť tip pre titulky"</string> <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Prekrytie titulkov"</string> <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"povoliť"</string> @@ -1039,6 +1039,13 @@ <item quantity="other">Bolo pridaných <xliff:g id="NUMBER_1">%s</xliff:g> ovládacích prvkov.</item> <item quantity="one">Bol pridaný <xliff:g id="NUMBER_0">%s</xliff:g> ovládací prvok.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Pridané medzi obľúbené, pozícia <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstránené z obľúbených"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"pridáte medzi obľúbené"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"odstránite z obľúbených"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Presunúť na pozíciu <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Ovládacie prvky"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Vyberte si ovládacie prvky, ku ktorým chcete mať prístup v ponuke vypínača"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Ovládacie prvky môžete usporiadať pridržaním a presunutím"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index cbfee80df294..0cf7e7cc2e41 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolniki dodani.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrolnikov dodanih.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Dodano med priljubljene, položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Odstranjeno iz priljubljenih"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"dodajanje med priljubljene"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"odstranitev iz priljubljenih"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Premakni na položaj <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrolniki"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Izberite kontrolnike, do katerih želite imeti dostop prek menija za vklop/izklop"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Držite in povlecite, da prerazporedite kontrolnike"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index ea6652639dda..f8da01c31f2c 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">U shtuan <xliff:g id="NUMBER_1">%s</xliff:g> kontrolle.</item> <item quantity="one">U shtua <xliff:g id="NUMBER_0">%s</xliff:g> kontroll.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"E hequr"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"E shtuar te të preferuarat, pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"E hequr nga të preferuarat"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ta shënosh si të preferuar"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ta heqësh nga të preferuarat"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Zhvendose te pozicioni <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontrollet"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Zgjidh kontrollet për të pasur qasje nga menyja e energjisë"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Mbaje të shtypur dhe zvarrit për të risistemuar kontrollet"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 17a01b223bb0..4a72d9dcbfca 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -1033,6 +1033,13 @@ <item quantity="few"><xliff:g id="NUMBER_1">%s</xliff:g> контроле су додате.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> контрола је додато.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Означено је као омиљено, <xliff:g id="NUMBER">%d</xliff:g>. позиција"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Уклоњено је из омиљених"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"означили као омиљено"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"уклонили из омиљених"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Преместите на <xliff:g id="NUMBER">%d</xliff:g>. позицију"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Контроле"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Одаберите контроле којима ћете приступати из менија напајања"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Задржите и превуците да бисте променили распоред контрола"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 7ff1f84d1668..dd76429b7469 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -512,7 +512,7 @@ <string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"Inkommande"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ljudlösa aviseringar"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Aviseringar med vibration eller ljud"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Aviseringar med vibrationer eller ljud"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Rensa alla ljudlösa aviseringar"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Aviseringar har pausats via Stör ej"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontroller har lagts till.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontroll har lagts till.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Har lagts till som favorit, plats <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Har tagits bort från favoriter"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"lägga till som favorit"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ta bort från favoriter"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Flytta till position <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontroller"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Välj snabbkontroller som ska visas i strömbrytarmenyn"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Ändra ordning på kontrollerna genom att trycka och dra"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 51d1a172f83e..652c6b3c1bf8 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Umeweka vidhibiti <xliff:g id="NUMBER_1">%s</xliff:g>.</item> <item quantity="one">Umeweka kidhibiti <xliff:g id="NUMBER_0">%s</xliff:g>.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kimewekwa kwenye vipendwa, nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Kimeondolewa kwenye vipendwa"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"weka kwenye vipendwa"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ondoa kwenye vipendwa"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Sogeza kwenye nafasi ya <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Vidhibiti"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Chagua vidhibiti vya kufikia ukitumia menyu ya kuwasha/kuzima"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Shikilia na uburute ili upange upya vidhibiti"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 1bea16e9b260..6010be6192f9 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> கட்டுப்பாடுகள் சேர்க்கப்பட்டன.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> கட்டுப்பாடு சேர்க்கப்பட்டது.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"பிடித்தவற்றில் சேர்க்கப்பட்டது, நிலை <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"பிடித்தவற்றிலிருந்து நீக்கப்பட்டது"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"பிடித்தவற்றில் சேர்க்க இருமுறை தட்டவும்"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"பிடித்தவற்றிலிருந்து நீக்க இருமுறை தட்டவும்"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>ம் நிலைக்கு நகர்த்து"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"கட்டுப்பாடுகள்"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"பவர் மெனுவில் இருந்து அணுகுவதற்கான கட்டுப்பாடுகளைத் தேர்ந்தெடுக்கலாம்"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"கட்டுப்பாடுகளை மறுவரிசைப்படுத்த அவற்றைப் பிடித்து இழுக்கவும்"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 42afdcfce94b..3c2ada7f1faf 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -365,7 +365,7 @@ <string name="quick_settings_rotation_locked_landscape_label" msgid="2000295772687238645">"ల్యాండ్స్కేప్"</string> <string name="quick_settings_ime_label" msgid="3351174938144332051">"ఇన్పుట్ పద్ధతి"</string> <string name="quick_settings_location_label" msgid="2621868789013389163">"లొకేషన్"</string> - <string name="quick_settings_location_off_label" msgid="7923929131443915919">"స్థానం ఆఫ్లో ఉంది"</string> + <string name="quick_settings_location_off_label" msgid="7923929131443915919">"లొకేషన్ ఆఫ్లో ఉంది"</string> <string name="quick_settings_media_device_label" msgid="8034019242363789941">"ప్రసార మాధ్యమ పరికరం"</string> <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string> <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ఎమర్జెన్సీ కాల్స్ మాత్రమే"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> కంట్రోల్లు యాడ్ అయ్యాయి.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> కంట్రోల్ యాడ్ అయింది.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"<xliff:g id="NUMBER">%d</xliff:g>వ స్థానంలో ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ఇష్టమైనదిగా పెట్టిన గుర్తు తీసివేయబడింది"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ఇష్టమైనదిగా గుర్తు పెట్టు"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"ఇష్టమైనదిగా పెట్టిన గుర్తును తీసివేయి"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g> పొజిషన్కు తరలించండి"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"నియంత్రణలు"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"పవర్ మెనూ నుండి యాక్సెస్ చేయడానికి నియంత్రణలను ఎంచుకోండి"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"నియంత్రణల క్రమం మార్చడానికి పట్టుకుని&amp, లాగండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index ee6b42262ce0..3ee8638d0966 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -710,8 +710,8 @@ <string name="notification_alert_title" msgid="7629202599338071971">"แจ้งเตือน"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"บับเบิล"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"ช่วยรักษาสมาธิของคุณด้วยการไม่ส่งเสียงหรือสั่น"</string> - <string name="notification_channel_summary_default" msgid="3539949463907902037">"ดึงความสนใจของคุณด้วยเสียงและการสั่น"</string> - <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ดึงความสนใจของคุณด้วยเสียงและการสั่น การสนทนาจาก <xliff:g id="APP_NAME">%1$s</xliff:g> จะแสดงเป็นบับเบิลโดยค่าเริ่มต้น"</string> + <string name="notification_channel_summary_default" msgid="3539949463907902037">"ดึงความสนใจของคุณด้วยเสียงหรือการสั่น"</string> + <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"ดึงความสนใจของคุณด้วยเสียงหรือการสั่น การสนทนาจาก <xliff:g id="APP_NAME">%1$s</xliff:g> จะแสดงเป็นบับเบิลโดยค่าเริ่มต้น"</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"ดึงดูดความสนใจของคุณไว้เสมอด้วยทางลัดแบบลอยที่มายังเนื้อหานี้"</string> <string name="notification_channel_summary_priority" msgid="7415770044553264622">"แสดงที่ด้านบนของส่วนการสนทนาและปรากฏเป็นบับเบิล"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"การตั้งค่า"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">เพิ่มตัวควบคุม <xliff:g id="NUMBER_1">%s</xliff:g> ตัวแล้ว</item> <item quantity="one">เพิ่มตัวควบคุม <xliff:g id="NUMBER_0">%s</xliff:g> ตัวแล้ว</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"นำออกแล้ว"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"ตั้งเป็นรายการโปรดแล้ว"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"ตั้งเป็นรายการโปรดแล้ว โดยอยู่ลำดับที่ <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"นำออกจากรายการโปรดแล้ว"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"ตั้งเป็นรายการโปรด"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"นำออกจากรายการโปรด"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"ย้ายไปที่ตำแหน่ง <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"การควบคุม"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"เลือกตัวควบคุมที่ต้องการให้เข้าถึงได้จากเมนูเปิด/ปิด"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"กดตัวควบคุมค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index db26407d03a0..2b26931fd1af 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -713,7 +713,7 @@ <string name="notification_channel_summary_default" msgid="3539949463907902037">"Kinukuha ang iyong atensyon sa pamamagitan ng tunog o pag-vibrate."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Kinukuha ang iyong atensyon sa pamamagitan ng tunog o pag-vibrate. Mga pag-uusap mula sa <xliff:g id="APP_NAME">%1$s</xliff:g> bubble bilang default."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Pinapanatili ang iyong atensyon sa pamamagitan ng lumulutang na shortcut sa content na ito."</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Lumalabas sa itaas ng seksyon ng pag-uusap at nagpapakita bilang bubble."</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Makikita sa itaas ng seksyon ng pag-uusap at lalabas bilang bubble"</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Mga Setting"</string> <string name="notification_priority_title" msgid="2079708866333537093">"Priyoridad"</string> <string name="no_shortcut" msgid="7176375126961212514">"Hindi sinusuportahan ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang mga setting na partikular sa pag-uusap"</string> @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol ang naidagdag.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> na kontrol ang naidagdag.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Inalis"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Ginawang paborito"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Ginawang paborito, posisyon <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Inalis sa paborito"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"gawing paborito"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"alisin sa paborito"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Ilipat sa posisyong <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Mga Kontrol"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Pumili ng mga kontrol na maa-access mula sa power menu"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"I-hold at i-drag para baguhin ang pagkakaayos ng mga kontrol"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 10779050d350..7e35a7745c62 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> kontrol eklendi.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> kontrol eklendi.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorilere eklendi, konum: <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Favorilerden kaldırıldı"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"favorilere ekleyin"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"favorilerden kaldırın"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>. konuma taşı"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Kontroller"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Güç menüsünden erişmek için denetimleri seçin"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Kontrolleri yeniden düzenlemek için basılı tutup sürükleyin"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 2ad54653d1a8..97157a4243d8 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -1039,6 +1039,13 @@ <item quantity="many">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елементів керування.</item> <item quantity="other">Додано <xliff:g id="NUMBER_1">%s</xliff:g> елемента керування.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Додано у вибране, позиція <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Видалено з вибраного"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"додати у вибране"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"видалити з вибраного"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Перемістити на позицію <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Елементи керування"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Виберіть, які елементи керування будуть у меню \"Живлення\""</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Щоб змінити порядок елементів керування, перетягуйте їх"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index b8c01720f9f3..3263d6d02ea3 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -586,7 +586,7 @@ <string name="accessibility_volume_settings" msgid="1458961116951564784">"صوتی ترتیبات"</string> <string name="accessibility_volume_expand" msgid="7653070939304433603">"پھیلائیں"</string> <string name="accessibility_volume_collapse" msgid="2746845391013829996">"سکیڑیں"</string> - <string name="volume_odi_captions_tip" msgid="8825655463280990941">"خودکار طور پر کیپشن میڈیا"</string> + <string name="volume_odi_captions_tip" msgid="8825655463280990941">"خودکار طور پر میڈیا پر کیپشن لگائیں"</string> <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"کیپشنز کی تجویز بند کریں"</string> <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"کیپشنز کا اوورلے"</string> <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"فعال کریں"</string> @@ -1013,7 +1013,7 @@ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"گفتگو کے سیکشن میں سب سے اوپر دکھائیں"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"مقفل سکرین پر پروفائل کی تصویر دکھائیں"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ایپس کے سب سے اوپر فلوٹنگ بلبلہ کے طور پر ظاہر ہوں"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"مداخلت کریں ڈسٹرب نہ کریں"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"ڈسٹرب نہ کریں میں مداخلت کریں"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"سمجھ آ گئی"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"میگنیفیکیشن اوورلے ونڈو"</string> <string name="magnification_window_title" msgid="4863914360847258333">"میگنیفکیشن ونڈو"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> کنٹرولز شامل کر دیے گئے۔</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> کنٹرول شامل کر دیا گیا۔</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"پسند کردہ، پوزیشن <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ناپسند کردہ"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"پسندیدہ بنائیں"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"پسندیدگی ختم کریں"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"پوزیشن <xliff:g id="NUMBER">%d</xliff:g> میں منتقل کریں"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"کنٹرولز"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"پاور مینو سے رسائی حاصل کرنے کے لیے کنٹرولز کو منتخب کریں"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"کنٹرولز کو دوبارہ ترتیب دینے کے ليے پکڑیں اور گھسیٹیں"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 1d91bb79267f..7befe46044b5 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -512,7 +512,7 @@ <string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string> <string name="notification_section_header_incoming" msgid="5295312809341711367">"Kiruvchi"</string> <string name="notification_section_header_gentle" msgid="3044910806569985386">"Sokin bildirishnomalar"</string> - <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalarning yuborilishi"</string> + <string name="notification_section_header_alerting" msgid="3168140660646863240">"Ogohlantirishlar"</string> <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Barcha sokin bildirishnomalarni tozalash"</string> <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string> @@ -702,20 +702,20 @@ <string name="inline_minimize_button" msgid="1474436209299333445">"Kichraytirish"</string> <string name="inline_silent_button_silent" msgid="525243786649275816">"Tovushsiz"</string> <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Ovozsiz qolsin"</string> - <string name="inline_silent_button_alert" msgid="5705343216858250354">"Bildirishnoma yuborish"</string> + <string name="inline_silent_button_alert" msgid="5705343216858250354">"Ogohlantirish"</string> <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Signal berishda davom etilsin"</string> <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirishnoma kelmasin"</string> <string name="inline_keep_showing_app" msgid="4393429060390649757">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string> <string name="notification_silence_title" msgid="8608090968400832335">"Tovushsiz"</string> - <string name="notification_alert_title" msgid="7629202599338071971">"Bildirishnoma yuborish"</string> + <string name="notification_alert_title" msgid="7629202599338071971">"Ogohlantirish"</string> <string name="notification_bubble_title" msgid="8330481035191903164">"Pufaklar"</string> <string name="notification_channel_summary_low" msgid="7300447764759926720">"Bildirishnomalar tovush va tebranishsiz keladi."</string> <string name="notification_channel_summary_default" msgid="3539949463907902037">"Bildirishnomalar tovush va tebranish bilan keladi."</string> <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Bildirishnomalar tovush va tebranish bilan keladi. <xliff:g id="APP_NAME">%1$s</xliff:g> suhbatlari standart holatda bulutcha shaklida chiqadi."</string> <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Bu kontentni ochuvchi erkin yorliq diqqatingizda boʻladi."</string> - <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Suhbatlar boʻlimining yuqori qismida bulutcha shaklida chiqadi."</string> + <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Suhbatlar ruknining tepasida bulutcha shaklida chiqadi."</string> <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Sozlamalar"</string> - <string name="notification_priority_title" msgid="2079708866333537093">"Muhimligi"</string> + <string name="notification_priority_title" msgid="2079708866333537093">"Muhim"</string> <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasida suhbat sozlamalari ishlamaydi"</string> <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Avvalgi bulutchalar topilmadi"</string> <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Bu yerda oxirgi va yopilgan bulutcha shaklidagi bildirishnomalar chiqadi"</string> @@ -1010,10 +1010,10 @@ <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string> <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string> <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Kutib turing"</string> - <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Suhbatlar qismining tepasida koʻrsatish"</string> - <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ekran qulfida profil rasmini koʻrsatish"</string> + <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Suhbatlar ruknining tepasida chiqarish"</string> + <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Ekran qulfida profil rasmini chiqarish"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Ilovalar ustida bulutchali xabar sifatida chiqadi"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"“Bezovta qilinmasin” rejimida koʻrsatish"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Bezovta qilinmasin rejimida chiqarish"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"OK"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"Kattalashtirish oynasining ustidan ochilishi"</string> <string name="magnification_window_title" msgid="4863914360847258333">"Kattalashtirish oynasi"</string> @@ -1027,6 +1027,13 @@ <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ta nazorat kiritilgan.</item> <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> ta nazorat kiritilgan.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Saralanganlarga kiritilgan, <xliff:g id="NUMBER">%d</xliff:g>-joy"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Saralanganlardan olib tashlangan"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"saralanganlarga kiritish"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"saralanganlardan olib tashlash"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"<xliff:g id="NUMBER">%d</xliff:g>-joyga olish"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Boshqaruv elementlari"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Quvvat tugmasi menyusida chiqadigan boshqaruv elementlarini tanlang"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Boshqaruv elementlarini qayta tartiblash uchun ushlab torting"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 44f1497fd358..3f333f0dfd70 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">Đã thêm <xliff:g id="NUMBER_1">%s</xliff:g> tùy chọn điều khiển.</item> <item quantity="one">Đã thêm <xliff:g id="NUMBER_0">%s</xliff:g> tùy chọn điều khiển.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Được yêu thích, vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Không được yêu thích"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"đánh dấu là yêu thích"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"bỏ yêu thích"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Di chuyển tới vị trí số <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Các tùy chọn điều khiển"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Chọn các tùy chọn điều khiển để truy cập từ trình đơn nguồn"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Giữ và kéo để sắp xếp lại các tùy chọn điều khiển"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 0ed76b7f2082..ed4885c1b9f7 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -1013,7 +1013,7 @@ <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"显示在对话部分顶部"</string> <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"在锁定屏幕上显示个人资料照片"</string> <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"以悬浮对话泡的形式显示在应用之上"</string> - <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"中断“勿扰”模式"</string> + <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"中断勿扰模式"</string> <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"知道了"</string> <string name="magnification_overlay_title" msgid="6584179429612427958">"放大叠加窗口"</string> <string name="magnification_window_title" msgid="4863914360847258333">"放大窗口"</string> @@ -1027,6 +1027,13 @@ <item quantity="other">已添加 <xliff:g id="NUMBER_1">%s</xliff:g> 个控件。</item> <item quantity="one">已添加 <xliff:g id="NUMBER_0">%s</xliff:g> 个控件。</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已收藏,位置:<xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"收藏"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"取消收藏"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"移至位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"控件"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"选择要从电源菜单访问的控件"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住并拖动即可重新排列控件"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 9a7d951f61c1..66ef1ae2959d 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">已新增 <xliff:g id="NUMBER_1">%s</xliff:g> 個控制項。</item> <item quantity="one">已新增 <xliff:g id="NUMBER_0">%s</xliff:g> 個控制項。</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入至收藏位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"已取消收藏"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"加入收藏"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"取消收藏"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"移至位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"控制項"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"從電源選單選擇要存取的控制項"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住並拖曳便可重新排列控制項"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index b1ba86abd8d1..6480f197a542 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="other">已新增 <xliff:g id="NUMBER_1">%s</xliff:g> 個控制項。</item> <item quantity="one">已新增 <xliff:g id="NUMBER_0">%s</xliff:g> 個控制項。</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"已移除"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"已加入收藏,位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"從收藏中移除"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"加入收藏"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"從收藏中移除"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"移到位置 <xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"控制項"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"選擇要從電源選單存取的控制項"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"按住並拖曳即可重新排列控制項"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 2fe904a1ffba..28251f2fd322 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -1027,6 +1027,13 @@ <item quantity="one"><xliff:g id="NUMBER_1">%s</xliff:g> ukulawulwa okwengeziwe.</item> <item quantity="other"><xliff:g id="NUMBER_1">%s</xliff:g> ukulawulwa okwengeziwe.</item> </plurals> + <string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string> + <string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string> + <string name="accessibility_control_favorite_position" msgid="54220258048929221">"Kwenziwe intandokazi, isimo esiyi-<xliff:g id="NUMBER">%d</xliff:g>"</string> + <string name="accessibility_control_not_favorite" msgid="1291760269563092359">"Akwenziwanga intandokazi"</string> + <string name="accessibility_control_change_favorite" msgid="2943178027582253261">"intandokazi"</string> + <string name="accessibility_control_change_unfavorite" msgid="6997408061750740327">"susa ubuntandokazi"</string> + <string name="accessibility_control_move" msgid="8980344493796647792">"Hambisa ukuze ubeke ku-<xliff:g id="NUMBER">%d</xliff:g>"</string> <string name="controls_favorite_default_title" msgid="967742178688938137">"Izilawuli"</string> <string name="controls_favorite_subtitle" msgid="6604402232298443956">"Khetha izilawuli ukuze ufinyelele kusuka kumenyu yamandla"</string> <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Bamba futhi uhudule ukuze uphinde ulungise izilawuli"</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 4f42370483c4..52ace2bd409b 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -758,6 +758,7 @@ <!-- used to override dark/light theming --> <item name="*android:colorBackgroundFloating">@color/GM2_grey_800</item> <item name="*android:colorPopupBackground">@color/GM2_grey_800</item> + <item name="*android:dialogCornerRadius">8dp</item> </style> <style name="TextAppearance.ControlSetup"> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 806678f23bb3..cffc10f65f1e 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -51,6 +51,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; @@ -78,6 +79,9 @@ public class ActivityManagerWrapper { public static final String CLOSE_SYSTEM_WINDOWS_REASON_RECENTS = "recentapps"; public static final String CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY = "homekey"; + // Should match the value in AssistManager + private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms"; + private final PackageManager mPackageManager; private final BackgroundExecutor mBackgroundExecutor; private final TaskStackChangeListeners mTaskStackChangeListeners; @@ -511,6 +515,8 @@ public class ActivityManagerWrapper { if (service == null) { return false; } + args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime()); + try { return service.showSessionFromSession(token, args, flags); } catch (RemoteException e) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index a578f337cca2..2587369cf0f5 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -185,9 +185,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Used to post to main UI thread private Handler mHandler = new Handler(); - /** LayoutParams used to add the BubbleStackView to the window maanger. */ + /** LayoutParams used to add the BubbleStackView to the window manager. */ private WindowManager.LayoutParams mWmLayoutParams; - + /** Whether or not the BubbleStackView has been added to the WindowManager. */ + private boolean mAddedToWindowManager = false; // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); @@ -595,9 +596,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (mStackView == null) { mStackView = new BubbleStackView( mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator, - mSysUiState, mNotificationShadeWindowController); + mSysUiState, mNotificationShadeWindowController, this::onAllBubblesAnimatedOut); mStackView.addView(mBubbleScrim); - addToWindowManager(); if (mExpandListener != null) { mStackView.setExpandListener(mExpandListener); } @@ -605,10 +605,17 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView.setUnbubbleConversationCallback(notificationEntry -> onUserChangedBubble(notificationEntry, false /* shouldBubble */)); } + + addToWindowManagerMaybe(); } - /** Adds the BubbleStackView to the WindowManager. */ - private void addToWindowManager() { + /** Adds the BubbleStackView to the WindowManager if it's not already there. */ + private void addToWindowManagerMaybe() { + // If the stack is null, or already added, don't add it. + if (mStackView == null || mAddedToWindowManager) { + return; + } + mWmLayoutParams = new WindowManager.LayoutParams( // Fill the screen so we can use translation animations to position the bubble // stack. We'll use touchable regions to ignore touches that are not on the bubbles @@ -629,9 +636,37 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mWmLayoutParams.packageName = mContext.getPackageName(); mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - mWindowManager.addView(mStackView, mWmLayoutParams); + try { + mAddedToWindowManager = true; + mWindowManager.addView(mStackView, mWmLayoutParams); + } catch (IllegalStateException e) { + // This means the stack has already been added. This shouldn't happen, since we keep + // track of that, but just in case, update the previously added view's layout params. + e.printStackTrace(); + updateWmFlags(); + } + } + + /** Removes the BubbleStackView from the WindowManager if it's there. */ + private void removeFromWindowManagerMaybe() { + if (!mAddedToWindowManager) { + return; + } + + try { + mAddedToWindowManager = false; + mWindowManager.removeView(mStackView); + } catch (IllegalArgumentException e) { + // This means the stack has already been removed - it shouldn't happen, but ignore if it + // does, since we wanted it removed anyway. + e.printStackTrace(); + } } + /** + * Updates the BubbleStackView's WindowManager.LayoutParams, and updates the WindowManager with + * the new params if the stack has been added. + */ private void updateWmFlags() { if (isStackExpanded()) { // If we're expanded, we want to be focusable so that the ActivityView can receive focus @@ -643,7 +678,25 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } - mWindowManager.updateViewLayout(mStackView, mWmLayoutParams); + if (mStackView != null && mAddedToWindowManager) { + try { + mWindowManager.updateViewLayout(mStackView, mWmLayoutParams); + } catch (IllegalArgumentException e) { + // If the stack is somehow not there, ignore the attempt to update it. + e.printStackTrace(); + } + } + } + + /** + * Called by the BubbleStackView and whenever all bubbles have animated out, and none have been + * added in the meantime. + */ + private void onAllBubblesAnimatedOut() { + if (mStackView != null) { + mStackView.setVisibility(INVISIBLE); + removeFromWindowManagerMaybe(); + } } /** @@ -833,10 +886,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) { - if (mStackView == null) { - // Lazy init stack view when a bubble is created - ensureStackViewCreated(); - } + // Lazy init stack view when a bubble is created + ensureStackViewCreated(); + // If this is an interruptive notif, mark that it's interrupted if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) { notif.setInterruption(); @@ -1196,11 +1248,15 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (mStackView == null) { return; } - if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) { - // Bubbles only appear in unlocked shade - mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE); - } else if (mStackView != null) { + + if (mStatusBarStateListener.getCurrentState() != SHADE) { + // Bubbles don't appear over the locked shade. mStackView.setVisibility(INVISIBLE); + } else if (hasBubbles()) { + // If we're unlocked, show the stack if we have bubbles. If we don't have bubbles, the + // stack will be set to INVISIBLE in onAllBubblesAnimatedOut after the bubbles animate + // out. + mStackView.setVisibility(VISIBLE); } mStackView.updateContentDescription(); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index baf92dc7abe7..769740032509 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -250,6 +250,7 @@ public class BubbleExpandedView extends LinearLayout { mPointerDrawable = new ShapeDrawable(TriangleShape.create( mPointerWidth, mPointerHeight, true /* pointUp */)); + mPointerDrawable.setTint(Color.WHITE); mPointerView.setBackground(mPointerDrawable); mPointerView.setVisibility(INVISIBLE); @@ -311,14 +312,10 @@ public class BubbleExpandedView extends LinearLayout { void applyThemeAttrs() { final TypedArray ta = mContext.obtainStyledAttributes( - new int[] { - android.R.attr.colorBackgroundFloating, - android.R.attr.dialogCornerRadius}); - int bgColor = ta.getColor(0, Color.WHITE); - float cornerRadius = ta.getDimensionPixelSize(1, 0); + new int[] {android.R.attr.dialogCornerRadius}); + float cornerRadius = ta.getDimensionPixelSize(0, 0); ta.recycle(); - mPointerDrawable.setTint(bgColor); if (mActivityView != null && ScreenDecorationsUtils.supportsRoundedCornersOnWindows( mContext.getResources())) { mActivityView.setCornerRadius(cornerRadius); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 88f5eb0b250c..ec45f93b38ee 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -362,6 +362,10 @@ public class BubbleStackView extends FrameLayout new MagnetizedObject.MagnetListener() { @Override public void onStuckToTarget(@NonNull MagnetizedObject.MagneticTarget target) { + if (mExpandedAnimationController.getDraggedOutBubble() == null) { + return; + } + animateDesaturateAndDarken( mExpandedAnimationController.getDraggedOutBubble(), true); } @@ -369,6 +373,10 @@ public class BubbleStackView extends FrameLayout @Override public void onUnstuckFromTarget(@NonNull MagnetizedObject.MagneticTarget target, float velX, float velY, boolean wasFlungOut) { + if (mExpandedAnimationController.getDraggedOutBubble() == null) { + return; + } + animateDesaturateAndDarken( mExpandedAnimationController.getDraggedOutBubble(), false); @@ -383,6 +391,10 @@ public class BubbleStackView extends FrameLayout @Override public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { + if (mExpandedAnimationController.getDraggedOutBubble() == null) { + return; + } + mExpandedAnimationController.dismissDraggedOutBubble( mExpandedAnimationController.getDraggedOutBubble() /* bubble */, mDismissTargetContainer.getHeight() /* translationYBy */, @@ -656,7 +668,8 @@ public class BubbleStackView extends FrameLayout @Nullable SurfaceSynchronizer synchronizer, FloatingContentCoordinator floatingContentCoordinator, SysUiState sysUiState, - NotificationShadeWindowController notificationShadeWindowController) { + NotificationShadeWindowController notificationShadeWindowController, + Runnable allBubblesAnimatedOutAction) { super(context); mBubbleData = data; @@ -691,11 +704,18 @@ public class BubbleStackView extends FrameLayout mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding); int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); + final Runnable onBubbleAnimatedOut = () -> { + if (getBubbleCount() == 0) { + allBubblesAnimatedOutAction.run(); + } + }; + mStackAnimationController = new StackAnimationController( - floatingContentCoordinator, this::getBubbleCount); + floatingContentCoordinator, this::getBubbleCount, onBubbleAnimatedOut); mExpandedAnimationController = new ExpandedAnimationController( - mDisplaySize, mExpandedViewPadding, res.getConfiguration().orientation); + mDisplaySize, mExpandedViewPadding, res.getConfiguration().orientation, + onBubbleAnimatedOut); mSurfaceSynchronizer = synchronizer != null ? synchronizer : DEFAULT_SURFACE_SYNCHRONIZER; setUpUserEducation(); @@ -871,7 +891,7 @@ public class BubbleStackView extends FrameLayout } } - return false; + return true; }); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index f57cf42ce4ff..76ff1afef3f7 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -32,6 +32,7 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.util.animation.PhysicsAnimator; import com.android.systemui.util.magnetictarget.MagnetizedObject; import com.google.android.collect.Sets; @@ -69,6 +70,10 @@ public class ExpandedAnimationController */ private static final float FLING_TO_DISMISS_MIN_VELOCITY = 6000f; + private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfig = + new PhysicsAnimator.SpringConfig( + EXPAND_COLLAPSE_ANIM_STIFFNESS, SpringForce.DAMPING_RATIO_NO_BOUNCY); + /** Horizontal offset between bubbles, which we need to know to re-stack them. */ private float mStackOffsetPx; /** Space between status bar and bubbles in the expanded state. */ @@ -116,10 +121,17 @@ public class ExpandedAnimationController private int mExpandedViewPadding; + /** + * Callback to run whenever any bubble is animated out. The BubbleStackView will check if the + * end of this animation means we have no bubbles left, and notify the BubbleController. + */ + private Runnable mOnBubbleAnimatedOutAction; + public ExpandedAnimationController(Point displaySize, int expandedViewPadding, - int orientation) { + int orientation, Runnable onBubbleAnimatedOutAction) { updateResources(orientation, displaySize); mExpandedViewPadding = expandedViewPadding; + mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction; } /** @@ -355,8 +367,8 @@ public class ExpandedAnimationController } animationForChild(bubble) .withStiffness(SpringForce.STIFFNESS_HIGH) - .scaleX(1.1f) - .scaleY(1.1f) + .scaleX(0f) + .scaleY(0f) .translationY(bubble.getTranslationY() + translationYBy) .alpha(0f, after) .start(); @@ -500,18 +512,17 @@ public class ExpandedAnimationController @Override void onChildRemoved(View child, int index, Runnable finishRemoval) { - final PhysicsAnimationLayout.PhysicsPropertyAnimator animator = animationForChild(child); - // If we're removing the dragged-out bubble, that means it got dismissed. if (child.equals(getDraggedOutBubble())) { mMagnetizedBubbleDraggingOut = null; finishRemoval.run(); + mOnBubbleAnimatedOutAction.run(); } else { - animator.alpha(0f, finishRemoval /* endAction */) - .withStiffness(SpringForce.STIFFNESS_HIGH) - .withDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY) - .scaleX(1.1f) - .scaleY(1.1f) + PhysicsAnimator.getInstance(child) + .spring(DynamicAnimation.ALPHA, 0f) + .spring(DynamicAnimation.SCALE_X, 0f, mAnimateOutSpringConfig) + .spring(DynamicAnimation.SCALE_Y, 0f, mAnimateOutSpringConfig) + .withEndActions(finishRemoval, mOnBubbleAnimatedOutAction) .start(); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index a7d1be1a766a..942b9a74bb86 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -767,6 +767,10 @@ public class PhysicsAnimationLayout extends FrameLayout { int targetAnimDuration, TimeInterpolator targetAnimInterpolator, Runnable... pathAnimEndActions) { + if (mPathAnimator != null) { + mPathAnimator.cancel(); + } + mPathAnimator = ObjectAnimator.ofFloat( this, mCurrentPointOnPathXProperty, mCurrentPointOnPathYProperty, path); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index 2cfe1dde0b51..d52c35b48ccc 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -74,6 +74,10 @@ public class StackAnimationController extends private static final int FLING_FOLLOW_STIFFNESS = 20000; public static final float DEFAULT_BOUNCINESS = 0.9f; + private final PhysicsAnimator.SpringConfig mAnimateOutSpringConfig = + new PhysicsAnimator.SpringConfig( + ANIMATE_IN_STIFFNESS, SpringForce.DAMPING_RATIO_NO_BOUNCY); + /** * Friction applied to fling animations. Since the stack must land on one of the sides of the * screen, we want less friction horizontally so that the stack has a better chance of making it @@ -248,12 +252,19 @@ public class StackAnimationController extends /** Returns the number of 'real' bubbles (excluding the overflow bubble). */ private IntSupplier mBubbleCountSupplier; + /** + * Callback to run whenever any bubble is animated out. The BubbleStackView will check if the + * end of this animation means we have no bubbles left, and notify the BubbleController. + */ + private Runnable mOnBubbleAnimatedOutAction; + public StackAnimationController( FloatingContentCoordinator floatingContentCoordinator, - IntSupplier bubbleCountSupplier) { + IntSupplier bubbleCountSupplier, + Runnable onBubbleAnimatedOutAction) { mFloatingContentCoordinator = floatingContentCoordinator; mBubbleCountSupplier = bubbleCountSupplier; - + mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction; } /** @@ -448,6 +459,10 @@ public class StackAnimationController extends float friction, SpringForce spring, Float finalPosition) { + if (!isActiveController()) { + return; + } + Log.d(TAG, String.format("Flinging %s.", PhysicsAnimationLayout.getReadablePropertyName(property))); @@ -652,8 +667,8 @@ public class StackAnimationController extends public void animateStackDismissal(float translationYBy, Runnable after) { animationsForChildrenFromIndex(0, (index, animation) -> animation - .scaleX(0.5f) - .scaleY(0.5f) + .scaleX(0f) + .scaleY(0f) .alpha(0f) .translationY( mLayout.getChildAt(index).getTranslationY() + translationYBy) @@ -668,7 +683,7 @@ public class StackAnimationController extends DynamicAnimation.ViewProperty property, SpringForce spring, float vel, float finalPosition, @Nullable Runnable... after) { - if (mLayout.getChildCount() == 0) { + if (mLayout.getChildCount() == 0 || !isActiveController()) { return; } @@ -676,12 +691,22 @@ public class StackAnimationController extends PhysicsAnimationLayout.getReadablePropertyName(property), finalPosition)); + // Whether we're springing towards the touch location, rather than to a position on the + // sides of the screen. + final boolean isSpringingTowardsTouch = mSpringToTouchOnNextMotionEvent; + StackPositionProperty firstBubbleProperty = new StackPositionProperty(property); SpringAnimation springAnimation = new SpringAnimation(this, firstBubbleProperty) .setSpring(spring) .addEndListener((dynamicAnimation, b, v, v1) -> { - mRestingStackPosition.set(mStackPosition); + if (!isSpringingTowardsTouch) { + // If we're springing towards the touch position, don't save the + // resting position - the touch location is not a valid resting + // position. We'll set this when the stack springs to the left or + // right side of the screen after the touch gesture ends. + mRestingStackPosition.set(mStackPosition); + } if (after != null) { for (Runnable callback : after) { @@ -760,13 +785,11 @@ public class StackAnimationController extends @Override void onChildRemoved(View child, int index, Runnable finishRemoval) { - // Animate the removing view in the opposite direction of the stack. - final float xOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_X); - animationForChild(child) - .alpha(0f, finishRemoval /* after */) - .scaleX(ANIMATE_IN_STARTING_SCALE) - .scaleY(ANIMATE_IN_STARTING_SCALE) - .translationX(mStackPosition.x - (-xOffset * ANIMATE_TRANSLATION_FACTOR)) + PhysicsAnimator.getInstance(child) + .spring(DynamicAnimation.ALPHA, 0f) + .spring(DynamicAnimation.SCALE_X, 0f, mAnimateOutSpringConfig) + .spring(DynamicAnimation.SCALE_Y, 0f, mAnimateOutSpringConfig) + .withEndActions(finishRemoval, mOnBubbleAnimatedOutAction) .start(); // If there are other bubbles, pull them into the correct position. diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 3aa417ab904b..ab3329122edc 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -107,6 +107,7 @@ class ControlsUiControllerImpl @Inject constructor ( private var popup: ListPopupWindow? = null private var hidden = true private lateinit var dismissGlobalActions: Runnable + private val popupThemedContext = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) override val available: Boolean get() = controlsController.get().available @@ -283,7 +284,10 @@ class ControlsUiControllerImpl @Inject constructor ( val anchor = parent.requireViewById<ImageView>(R.id.controls_more) anchor.setOnClickListener(object : View.OnClickListener { override fun onClick(v: View) { - popup = GlobalActionsPopupMenu(context, false /* isDropDownMode */).apply { + popup = GlobalActionsPopupMenu( + popupThemedContext, + false /* isDropDownMode */ + ).apply { setAnchorView(anchor) setAdapter(adapter) setOnItemClickListener(object : AdapterView.OnItemClickListener { @@ -368,7 +372,7 @@ class ControlsUiControllerImpl @Inject constructor ( val spinner = parent.requireViewById<TextView>(R.id.app_or_structure_spinner).apply { setText(selectionItem.getTitle()) // override the default color on the dropdown drawable - (getBackground() as LayerDrawable).getDrawable(1) + (getBackground() as LayerDrawable).getDrawable(0) .setTint(context.resources.getColor(R.color.control_spinner_dropdown, null)) } @@ -380,13 +384,12 @@ class ControlsUiControllerImpl @Inject constructor ( val anchor = parent.requireViewById<ViewGroup>(R.id.controls_header) anchor.setOnClickListener(object : View.OnClickListener { override fun onClick(v: View) { - popup = GlobalActionsPopupMenu(context, true /* isDropDownMode */).apply { + popup = GlobalActionsPopupMenu( + popupThemedContext, + true /* isDropDownMode */ + ).apply { setAnchorView(anchor) setAdapter(adapter) - val theme = ContextThemeWrapper(context, R.style.Control_ListPopupWindow) - .getTheme() - setBackgroundDrawable( - context.resources.getDrawable(R.drawable.rounded_bg_full, theme)) setOnItemClickListener(object : AdapterView.OnItemClickListener { override fun onItemClick( diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java index 2b27436c85dd..3a8212cd733e 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java @@ -39,6 +39,7 @@ import android.content.res.Resources; import android.hardware.SensorPrivacyManager; import android.hardware.display.DisplayManager; import android.media.AudioManager; +import android.media.MediaRouter2Manager; import android.net.ConnectivityManager; import android.net.NetworkScoreManager; import android.net.wifi.WifiManager; @@ -211,6 +212,11 @@ public class SystemServicesModule { } @Provides + static MediaRouter2Manager provideMediaRouter2Manager(Context context) { + return MediaRouter2Manager.getInstance(context); + } + + @Provides @Singleton static NetworkScoreManager provideNetworkScoreManager(Context context) { return context.getSystemService(NetworkScoreManager.class); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index c66a09554ec3..ac289cb5f822 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -2047,7 +2047,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private ListPopupWindow createPowerOverflowPopup() { ListPopupWindow popup = new GlobalActionsPopupMenu( - mContext, false /* isDropDownMode */); + new ContextThemeWrapper( + mContext, + com.android.systemui.R.style.Control_ListPopupWindow + ), false /* isDropDownMode */); View overflowButton = findViewById(com.android.systemui.R.id.global_actions_overflow_button); popup.setAnchorView(overflowButton); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java index 02ea25128993..a5ced7b574b7 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPopupMenu.java @@ -19,7 +19,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; -import android.view.ContextThemeWrapper; import android.view.View; import android.view.View.MeasureSpec; import android.view.WindowManager; @@ -32,6 +31,8 @@ import com.android.systemui.R; /** * Customized widget for use in the GlobalActionsDialog. Ensures common positioning and user * interactions. + * + * It should be created with a {@link Context} with the right theme */ public class GlobalActionsPopupMenu extends ListPopupWindow { private Context mContext; @@ -42,15 +43,17 @@ public class GlobalActionsPopupMenu extends ListPopupWindow { private ListAdapter mAdapter; public GlobalActionsPopupMenu(@NonNull Context context, boolean isDropDownMode) { - super(new ContextThemeWrapper(context, R.style.Control_ListPopupWindow)); + super(context); mContext = context; + Resources res = mContext.getResources(); + setBackgroundDrawable( + res.getDrawable(R.drawable.rounded_bg_full, context.getTheme())); mIsDropDownMode = isDropDownMode; // required to show above the global actions dialog setWindowLayoutType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); setModal(true); - Resources res = mContext.getResources(); mGlobalActionsSidePadding = res.getDimensionPixelSize(R.dimen.global_actions_side_margin); if (!isDropDownMode) { mMenuVerticalPadding = res.getDimensionPixelSize(R.dimen.control_menu_vertical_padding); @@ -89,11 +92,16 @@ public class GlobalActionsPopupMenu extends ListPopupWindow { // width should be between [.5, .9] of screen int parentWidth = res.getSystem().getDisplayMetrics().widthPixels; int widthSpec = MeasureSpec.makeMeasureSpec( - (int) (parentWidth * 0.9), MeasureSpec.AT_MOST); - View child = mAdapter.getView(0, null, listView); - child.measure(widthSpec, MeasureSpec.UNSPECIFIED); - int width = Math.max(child.getMeasuredWidth(), (int) (parentWidth * 0.5)); - + (int) (parentWidth * 0.9) - 2 * mMenuHorizontalPadding, MeasureSpec.AT_MOST); + int maxWidth = 0; + for (int i = 0; i < mAdapter.getCount(); i++) { + View child = mAdapter.getView(i, null, listView); + child.measure(widthSpec, MeasureSpec.UNSPECIFIED); + int w = child.getMeasuredWidth(); + maxWidth = Math.max(w, maxWidth); + } + int width = Math.max(maxWidth, (int) (parentWidth * 0.5) - 2 * mMenuHorizontalPadding) + + 2 * mMenuHorizontalPadding; listView.setPadding(mMenuHorizontalPadding, mMenuVerticalPadding, mMenuHorizontalPadding, mMenuVerticalPadding); diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 90054d61c673..c7b93262b181 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -33,7 +33,6 @@ import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.Icon; import android.graphics.drawable.RippleDrawable; import android.media.session.MediaController; -import android.media.session.MediaController.PlaybackInfo; import android.media.session.MediaSession; import android.media.session.PlaybackState; import android.service.media.MediaBrowserService; @@ -294,14 +293,6 @@ public class MediaControlPanel { mActivityStarter.startActivity(intent, false, true /* dismissShade */, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); }); - final boolean isRemotePlayback; - PlaybackInfo playbackInfo = mController.getPlaybackInfo(); - if (playbackInfo != null) { - isRemotePlayback = playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; - } else { - Log.d(TAG, "PlaybackInfo was null. Defaulting to local playback."); - isRemotePlayback = false; - } ImageView iconView = mViewHolder.getSeamlessIcon(); TextView deviceName = mViewHolder.getSeamlessText(); @@ -312,18 +303,18 @@ public class MediaControlPanel { rect.setStroke(2, deviceName.getCurrentTextColor()); rect.setColor(Color.TRANSPARENT); - if (isRemotePlayback) { + final MediaDeviceData device = data.getDevice(); + if (device != null && !device.getEnabled()) { mViewHolder.getSeamless().setEnabled(false); // TODO(b/156875717): setEnabled should cause the alpha to change. mViewHolder.getSeamless().setAlpha(0.38f); iconView.setImageResource(R.drawable.ic_hardware_speaker); iconView.setVisibility(View.VISIBLE); deviceName.setText(R.string.media_seamless_remote_device); - } else if (data.getDevice() != null && data.getDevice().getIcon() != null - && data.getDevice().getName() != null) { + } else if (device != null) { mViewHolder.getSeamless().setEnabled(true); mViewHolder.getSeamless().setAlpha(1f); - Drawable icon = data.getDevice().getIcon(); + Drawable icon = device.getIcon(); iconView.setVisibility(View.VISIBLE); if (icon instanceof AdaptiveIcon) { @@ -333,7 +324,7 @@ public class MediaControlPanel { } else { iconView.setImageDrawable(icon); } - deviceName.setText(data.getDevice().getName()); + deviceName.setText(device.getName()); } else { // Reset to default Log.w(TAG, "device is null. Not binding output chip."); diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt index 41d411019921..330a5c0dcad3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt @@ -47,6 +47,7 @@ data class MediaAction( /** State of the media device. */ data class MediaDeviceData( + val enabled: Boolean, val icon: Drawable?, val name: String? ) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt index 2d16e2930365..0b04fd060766 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt @@ -16,8 +16,12 @@ package com.android.systemui.media +import android.app.Notification import android.content.Context import android.service.notification.StatusBarNotification +import android.media.MediaRouter2Manager +import android.media.session.MediaSession +import android.media.session.MediaController import com.android.settingslib.media.LocalMediaManager import com.android.settingslib.media.MediaDevice import com.android.systemui.dagger.qualifiers.Main @@ -32,6 +36,7 @@ import javax.inject.Singleton class MediaDeviceManager @Inject constructor( private val context: Context, private val localMediaManagerFactory: LocalMediaManagerFactory, + private val mr2manager: MediaRouter2Manager, private val featureFlag: MediaFeatureFlag, @Main private val fgExecutor: Executor ) { @@ -52,7 +57,10 @@ class MediaDeviceManager @Inject constructor( if (featureFlag.enabled && isMediaNotification(sbn)) { var tok = entries[key] if (tok == null) { - tok = Token(key, localMediaManagerFactory.create(sbn.packageName)) + val token = sbn.notification.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) + as MediaSession.Token? + val controller = MediaController(context, token) + tok = Token(key, controller, localMediaManagerFactory.create(sbn.packageName)) entries[key] = tok tok.start() } @@ -72,7 +80,8 @@ class MediaDeviceManager @Inject constructor( } private fun processDevice(key: String, device: MediaDevice?) { - val data = MediaDeviceData(device?.icon, device?.name) + val enabled = device != null + val data = MediaDeviceData(enabled, device?.icon, device?.name) listeners.forEach { it.onMediaDeviceChanged(key, data) } @@ -87,11 +96,13 @@ class MediaDeviceManager @Inject constructor( private inner class Token( val key: String, + val controller: MediaController, val localMediaManager: LocalMediaManager ) : LocalMediaManager.DeviceCallback { + private var started = false private var current: MediaDevice? = null set(value) { - if (value != field) { + if (!started || value != field) { field = value processDevice(key, value) } @@ -99,19 +110,28 @@ class MediaDeviceManager @Inject constructor( fun start() { localMediaManager.registerCallback(this) localMediaManager.startScan() - current = localMediaManager.getCurrentConnectedDevice() + updateCurrent() + started = true } fun stop() { + started = false localMediaManager.stopScan() localMediaManager.unregisterCallback(this) } override fun onDeviceListUpdate(devices: List<MediaDevice>?) = fgExecutor.execute { - current = localMediaManager.getCurrentConnectedDevice() + updateCurrent() } override fun onSelectedDeviceStateChanged(device: MediaDevice, state: Int) { fgExecutor.execute { - current = device + updateCurrent() } } + private fun updateCurrent() { + val device = localMediaManager.getCurrentConnectedDevice() + val route = mr2manager.getRoutingSessionForMediaController(controller) + // If we get a null route, then don't trust the device. Just set to null to disable the + // output switcher chip. + current = if (route != null) device else null + } } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java index 93605170f22e..febb6e9b32f5 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java @@ -194,6 +194,14 @@ public class PipBoundsHandler { mLastPipComponentName = null; } + /** + * Returns ture if there's a valid snap fraction. This is used with {@link EXTRA_IS_FIRST_ENTRY} + * to see if this is the first time user has entered PIP for the component. + */ + public boolean hasSaveReentryBounds() { + return mReentrySnapFraction != INVALID_SNAP_FRACTION; + } + public Rect getDisplayBounds() { return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index ae6100675cb4..c2f8cb9800d0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -58,6 +58,7 @@ import com.android.internal.os.SomeArgs; import com.android.systemui.R; import com.android.systemui.pip.phone.PipUpdateThread; import com.android.systemui.stackdivider.Divider; +import com.android.systemui.wm.DisplayController; import java.io.PrintWriter; import java.util.ArrayList; @@ -82,8 +83,10 @@ import javax.inject.Singleton; * see also {@link com.android.systemui.pip.phone.PipMotionHelper}. */ @Singleton -public class PipTaskOrganizer extends TaskOrganizer { +public class PipTaskOrganizer extends TaskOrganizer implements + DisplayController.OnDisplaysChangedListener { private static final String TAG = PipTaskOrganizer.class.getSimpleName(); + private static final boolean DEBUG = false; private static final int MSG_RESIZE_IMMEDIATE = 1; private static final int MSG_RESIZE_ANIMATE = 2; @@ -206,10 +209,17 @@ public class PipTaskOrganizer extends TaskOrganizer { mSurfaceControlTransactionFactory; private PictureInPictureParams mPictureInPictureParams; + /** + * If set to {@code true}, the entering animation will be skipped and we will wait for + * {@link #onFixedRotationFinished(int)} callback to actually enter PiP. + */ + private boolean mShouldDeferEnteringPip; + @Inject public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler, @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper, - @Nullable Divider divider) { + @Nullable Divider divider, + @NonNull DisplayController displayController) { mMainHandler = new Handler(Looper.getMainLooper()); mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks); mPipBoundsHandler = boundsHandler; @@ -219,6 +229,7 @@ public class PipTaskOrganizer extends TaskOrganizer { mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper); mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; mSplitDivider = divider; + displayController.addDisplayWindowListener(this); } public Handler getUpdateHandler() { @@ -281,7 +292,8 @@ public class PipTaskOrganizer extends TaskOrganizer { final int direction = syncWithSplitScreenBounds(destinationBounds) ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN; - final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds, mLastReportedBounds); tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height()); @@ -325,53 +337,67 @@ public class PipTaskOrganizer extends TaskOrganizer { @Override public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) { Objects.requireNonNull(info, "Requires RunningTaskInfo"); - mPictureInPictureParams = info.pictureInPictureParams; - final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( - info.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), - null /* bounds */, getMinimalSize(info.topActivityInfo)); - Objects.requireNonNull(destinationBounds, "Missing destination bounds"); mTaskInfo = info; mToken = mTaskInfo.token; mInPip = true; mLeash = leash; + mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration)); + mPictureInPictureParams = mTaskInfo.pictureInPictureParams; + + if (mShouldDeferEnteringPip) { + if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing"); + // if deferred, hide the surface till fixed rotation is completed + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + tx.setAlpha(mLeash, 0f); + tx.apply(); + return; + } - // TODO: Skip enter animation when entering pip from another orientation + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( + mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), + null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); + Objects.requireNonNull(destinationBounds, "Missing destination bounds"); final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); - mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration)); if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) { scheduleAnimateResizePip(currentBounds, destinationBounds, TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration, null /* updateBoundsCallback */); } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { - // If we are fading the PIP in, then we should move the pip to the final location as - // soon as possible, but set the alpha immediately since the transaction can take a - // while to process - final SurfaceControl.Transaction tx = new SurfaceControl.Transaction(); - tx.setAlpha(mLeash, 0f); - tx.apply(); - final WindowContainerTransaction wct = new WindowContainerTransaction(); - wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); - wct.setBounds(mToken, destinationBounds); - wct.scheduleFinishEnterPip(mToken, destinationBounds); - applySyncTransaction(wct, new WindowContainerTransactionCallback() { - @Override - public void onTransactionReady(int id, SurfaceControl.Transaction t) { - t.apply(); - mUpdateHandler.post(() -> mPipAnimationController - .getAnimator(mLeash, destinationBounds, 0f, 1f) - .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) - .setPipAnimationCallback(mPipAnimationCallback) - .setDuration(mEnterExitAnimationDuration) - .start()); - } - }); + enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration); mOneShotAnimationType = ANIM_TYPE_BOUNDS; } else { throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType); } } + private void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) { + // If we are fading the PIP in, then we should move the pip to the final location as + // soon as possible, but set the alpha immediately since the transaction can take a + // while to process + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + tx.setAlpha(mLeash, 0f); + tx.apply(); + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); + wct.setBounds(mToken, destinationBounds); + wct.scheduleFinishEnterPip(mToken, destinationBounds); + applySyncTransaction(wct, new WindowContainerTransactionCallback() { + @Override + public void onTransactionReady(int id, SurfaceControl.Transaction t) { + t.apply(); + mUpdateHandler.post(() -> mPipAnimationController + .getAnimator(mLeash, destinationBounds, 0f, 1f) + .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP) + .setPipAnimationCallback(mPipAnimationCallback) + .setDuration(durationMs) + .start()); + } + }); + } + /** * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}. * Meanwhile this callback is invoked whenever the task is removed. For instance: @@ -391,6 +417,7 @@ public class PipTaskOrganizer extends TaskOrganizer { Log.wtf(TAG, "Unrecognized token: " + token); return; } + mShouldDeferEnteringPip = false; mPictureInPictureParams = null; mInPip = false; } @@ -399,7 +426,7 @@ public class PipTaskOrganizer extends TaskOrganizer { public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken"); final PictureInPictureParams newParams = info.pictureInPictureParams; - if (!applyPictureInPictureParams(newParams)) { + if (newParams == null || !applyPictureInPictureParams(newParams)) { Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams); return; } @@ -416,6 +443,23 @@ public class PipTaskOrganizer extends TaskOrganizer { // Do nothing } + @Override + public void onFixedRotationStarted(int displayId, int newRotation) { + mShouldDeferEnteringPip = true; + } + + @Override + public void onFixedRotationFinished(int displayId) { + if (mShouldDeferEnteringPip && mInPip) { + final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds( + mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams), + null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo)); + // schedule a regular animation to ensure all the callbacks are still being sent + enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */); + } + mShouldDeferEnteringPip = false; + } + /** * TODO(b/152809058): consolidate the display info handling logic in SysUI * @@ -476,6 +520,10 @@ public class PipTaskOrganizer extends TaskOrganizer { */ public void scheduleAnimateResizePip(Rect toBounds, int duration, Consumer<Rect> updateBoundsCallback) { + if (mShouldDeferEnteringPip) { + Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred"); + return; + } scheduleAnimateResizePip(mLastReportedBounds, toBounds, TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback); } @@ -567,6 +615,10 @@ public class PipTaskOrganizer extends TaskOrganizer { // can be initiated in other component, ignore if we are no longer in PIP return; } + if (mShouldDeferEnteringPip) { + Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred"); + return; + } SomeArgs args = SomeArgs.obtain(); args.arg1 = updateBoundsCallback; args.arg2 = originalBounds; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java index 69bad80082e4..461fdef2b755 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java @@ -29,6 +29,7 @@ import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CON import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MENU_STATE; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_MENU_WITH_DELAY; +import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_SHOW_RESIZE_HANDLE; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_STACK_BOUNDS; import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_WILL_RESIZE_MENU; import static com.android.systemui.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE; @@ -119,6 +120,7 @@ public class PipMenuActivity extends Activity { private LinearLayout mActionsGroup; private View mSettingsButton; private View mDismissButton; + private View mResizeHandle; private int mBetweenActionPaddingLand; private AnimatorSet mMenuContainerAnimator; @@ -142,7 +144,8 @@ public class PipMenuActivity extends Activity { data.getParcelable(EXTRA_STACK_BOUNDS), data.getBoolean(EXTRA_ALLOW_TIMEOUT), data.getBoolean(EXTRA_WILL_RESIZE_MENU), - data.getBoolean(EXTRA_SHOW_MENU_WITH_DELAY)); + data.getBoolean(EXTRA_SHOW_MENU_WITH_DELAY), + data.getBoolean(EXTRA_SHOW_RESIZE_HANDLE)); break; } case MESSAGE_POKE_MENU: @@ -212,6 +215,8 @@ public class PipMenuActivity extends Activity { expandPip(); } }); + mResizeHandle = findViewById(R.id.resize_handle); + mResizeHandle.setAlpha(0); mActionsGroup = findViewById(R.id.actions_group); mBetweenActionPaddingLand = getResources().getDimensionPixelSize( R.dimen.pip_between_action_padding_land); @@ -342,7 +347,7 @@ public class PipMenuActivity extends Activity { } private void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout, - boolean resizeMenuOnShow, boolean withDelay) { + boolean resizeMenuOnShow, boolean withDelay, boolean showResizeHandle) { mAllowMenuTimeout = allowMenuTimeout; if (mMenuState != menuState) { // Disallow touches if the menu needs to resize while showing, and we are transitioning @@ -363,10 +368,14 @@ public class PipMenuActivity extends Activity { mSettingsButton.getAlpha(), 1f); ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA, mDismissButton.getAlpha(), 1f); + ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA, + mResizeHandle.getAlpha(), menuState == MENU_STATE_CLOSE && showResizeHandle + ? 1f : 0f); if (menuState == MENU_STATE_FULL) { - mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim); + mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, + resizeAnim); } else { - mMenuContainerAnimator.playTogether(dismissAnim); + mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim); } mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN); mMenuContainerAnimator.setDuration(MENU_FADE_DURATION); @@ -399,11 +408,12 @@ public class PipMenuActivity extends Activity { } private void hideMenu(Runnable animationEndCallback) { - hideMenu(animationEndCallback, true /* notifyMenuVisibility */, false /* isDismissing */); + hideMenu(animationEndCallback, true /* notifyMenuVisibility */, false /* isDismissing */, + true /* animate */); } private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility, - boolean isDismissing) { + boolean isDismissing, boolean animate) { if (mMenuState != MENU_STATE_NONE) { cancelDelayedFinish(); if (notifyMenuVisibility) { @@ -417,9 +427,11 @@ public class PipMenuActivity extends Activity { mSettingsButton.getAlpha(), 0f); ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA, mDismissButton.getAlpha(), 0f); - mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim); + ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA, + mResizeHandle.getAlpha(), 0f); + mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim); mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT); - mMenuContainerAnimator.setDuration(MENU_FADE_DURATION); + mMenuContainerAnimator.setDuration(animate ? MENU_FADE_DURATION : 0); mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -462,7 +474,9 @@ public class PipMenuActivity extends Activity { boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true); boolean willResizeMenu = intent.getBooleanExtra(EXTRA_WILL_RESIZE_MENU, false); boolean withDelay = intent.getBooleanExtra(EXTRA_SHOW_MENU_WITH_DELAY, false); - showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay); + boolean showResizeHandle = intent.getBooleanExtra(EXTRA_SHOW_RESIZE_HANDLE, false); + showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay, + showResizeHandle); } } @@ -582,16 +596,20 @@ public class PipMenuActivity extends Activity { hideMenu(() -> { sendEmptyMessage(PipMenuActivityController.MESSAGE_EXPAND_PIP, "Could not notify controller to expand PIP"); - }, false /* notifyMenuVisibility */, false /* isDismissing */); + }, false /* notifyMenuVisibility */, false /* isDismissing */, true /* animate */); } private void dismissPip() { + // Since tapping on the close-button invokes a double-tap wait callback in PipTouchHandler, + // we want to disable animating the fadeout animation of the buttons in order to call on + // PipTouchHandler#onPipDismiss fast enough. + final boolean animate = mMenuState != MENU_STATE_CLOSE; // Do not notify menu visibility when hiding the menu, the controller will do this when it // handles the message hideMenu(() -> { sendEmptyMessage(PipMenuActivityController.MESSAGE_DISMISS_PIP, "Could not notify controller to dismiss PIP"); - }, false /* notifyMenuVisibility */, true /* isDismissing */); + }, false /* notifyMenuVisibility */, true /* isDismissing */, animate); } private void showSettings() { diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java index 1608f833c169..36a9a34dce17 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java @@ -65,6 +65,7 @@ public class PipMenuActivityController { public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction"; public static final String EXTRA_MENU_STATE = "menu_state"; public static final String EXTRA_SHOW_MENU_WITH_DELAY = "show_menu_with_delay"; + public static final String EXTRA_SHOW_RESIZE_HANDLE = "show_resize_handle"; public static final int MESSAGE_MENU_STATE_CHANGED = 100; public static final int MESSAGE_EXPAND_PIP = 101; @@ -248,7 +249,7 @@ public class PipMenuActivityController { // start, then start it startMenuActivity(MENU_STATE_NONE, null /* stackBounds */, false /* allowMenuTimeout */, false /* resizeMenuOnShow */, - false /* withDelay */); + false /* withDelay */, false /* showResizeHandle */); } } @@ -257,28 +258,29 @@ public class PipMenuActivityController { * PiP window transition is finished. */ public void showMenuWithDelay(int menuState, Rect stackBounds, boolean allowMenuTimeout, - boolean willResizeMenu) { + boolean willResizeMenu, boolean showResizeHandle) { showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu, - true /* withDelay */); + true /* withDelay */, showResizeHandle); } /** * Shows the menu activity immediately. */ public void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout, - boolean willResizeMenu) { + boolean willResizeMenu, boolean showResizeHandle) { showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu, - false /* withDelay */); + false /* withDelay */, showResizeHandle); } private void showMenuInternal(int menuState, Rect stackBounds, boolean allowMenuTimeout, - boolean willResizeMenu, boolean withDelay) { + boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) { if (DEBUG) { Log.d(TAG, "showMenu() state=" + menuState + " hasActivity=" + (mToActivityMessenger != null) + " allowMenuTimeout=" + allowMenuTimeout + " willResizeMenu=" + willResizeMenu + " withDelay=" + withDelay + + " showResizeHandle=" + showResizeHandle + " callers=\n" + Debug.getCallers(5, " ")); } @@ -291,6 +293,7 @@ public class PipMenuActivityController { data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); data.putBoolean(EXTRA_WILL_RESIZE_MENU, willResizeMenu); data.putBoolean(EXTRA_SHOW_MENU_WITH_DELAY, withDelay); + data.putBoolean(EXTRA_SHOW_RESIZE_HANDLE, showResizeHandle); Message m = Message.obtain(); m.what = PipMenuActivity.MESSAGE_SHOW_MENU; m.obj = data; @@ -302,7 +305,8 @@ public class PipMenuActivityController { } else if (!mStartActivityRequested || isStartActivityRequestedElapsed()) { // If we haven't requested the start activity, or if it previously took too long to // start, then start it - startMenuActivity(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay); + startMenuActivity(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay, + showResizeHandle); } } @@ -405,7 +409,7 @@ public class PipMenuActivityController { * Starts the menu activity on the top task of the pinned stack. */ private void startMenuActivity(int menuState, Rect stackBounds, boolean allowMenuTimeout, - boolean willResizeMenu, boolean withDelay) { + boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) { try { StackInfo pinnedStackInfo = ActivityTaskManager.getService().getStackInfo( WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); @@ -422,6 +426,7 @@ public class PipMenuActivityController { intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); intent.putExtra(EXTRA_WILL_RESIZE_MENU, willResizeMenu); intent.putExtra(EXTRA_SHOW_MENU_WITH_DELAY, withDelay); + intent.putExtra(EXTRA_SHOW_RESIZE_HANDLE, showResizeHandle); ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); options.setLaunchTaskId( pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index d0995972e8a8..74c72fd356a0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -237,7 +237,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig) .withEndActions(() -> mSpringingToTouch = false); - startBoundsAnimator(toBounds.left /* toX */, toBounds.top /* toY */); + startBoundsAnimator(toBounds.left /* toX */, toBounds.top /* toY */, + false /* dismiss */); } } @@ -334,7 +335,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, final float estimatedFlingYEndValue = PhysicsAnimator.estimateFlingEndValue(mBounds.top, velocityY, mFlingConfigY); - startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */); + startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */, + false /* dismiss */); } /** @@ -346,30 +348,26 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mAnimatedBoundsPhysicsAnimator .spring(FloatProperties.RECT_X, bounds.left, springConfig) .spring(FloatProperties.RECT_Y, bounds.top, springConfig); - startBoundsAnimator(bounds.left /* toX */, bounds.top /* toY */); + startBoundsAnimator(bounds.left /* toX */, bounds.top /* toY */, + false /* dismiss */); } /** * Animates the dismissal of the PiP off the edge of the screen. */ - void animateDismiss(float velocityX, float velocityY, @Nullable Runnable updateAction) { + void animateDismiss() { mAnimatedBounds.set(mBounds); // Animate off the bottom of the screen, then dismiss PIP. mAnimatedBoundsPhysicsAnimator .spring(FloatProperties.RECT_Y, mBounds.bottom + mBounds.height(), - velocityY, + 0, mSpringConfig) .withEndActions(this::dismissPip); - // If we were provided with an update action, run it whenever there's an update. - if (updateAction != null) { - mAnimatedBoundsPhysicsAnimator.addUpdateListener( - (target, values) -> updateAction.run()); - } - - startBoundsAnimator(mBounds.left /* toX */, mBounds.bottom + mBounds.height() /* toY */); + startBoundsAnimator(mBounds.left /* toX */, mBounds.bottom + mBounds.height() /* toY */, + true /* dismiss */); } /** @@ -440,7 +438,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, * This will also add end actions to the bounds animator that cancel the TimeAnimator and update * the 'real' bounds to equal the final animated bounds. */ - private void startBoundsAnimator(float toX, float toY) { + private void startBoundsAnimator(float toX, float toY, boolean dismiss) { if (!mSpringingToTouch) { cancelAnimations(); } @@ -456,7 +454,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mAnimatedBoundsPhysicsAnimator .withEndActions(() -> { - mPipTaskOrganizer.scheduleFinishResizePip(mAnimatedBounds); + if (!dismiss) { + mPipTaskOrganizer.scheduleFinishResizePip(mAnimatedBounds); + } mAnimatingToBounds.setEmpty(); }) .addUpdateListener(mResizePipUpdateListener) diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index af9dd574c8af..ecd80a301d52 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -197,13 +197,14 @@ public class PipTouchHandler { if (topPipActivity.first != null) { MetricsLoggerWrapper.logPictureInPictureDismissByTap(mContext, topPipActivity); } + mTouchState.removeDoubleTapTimeoutCallback(); mMotionHelper.dismissPip(); } @Override public void onPipShowMenu() { mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, willResizeMenu()); + true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()); } } @@ -235,7 +236,7 @@ public class PipTouchHandler { this::updateMovementBounds); mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler, () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, willResizeMenu())); + true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle())); Resources res = context.getResources(); mExpandedShortestEdgeSize = res.getDimensionPixelSize( @@ -297,7 +298,7 @@ public class PipTouchHandler { @Override public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { mHandler.post(() -> { - mMotionHelper.animateDismiss(0, 0, null); + mMotionHelper.animateDismiss(); hideDismissTarget(); }); @@ -310,6 +311,10 @@ public class PipTouchHandler { mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView); } + private boolean shouldShowResizeHandle() { + return !mPipBoundsHandler.hasSaveReentryBounds(); + } + public void setTouchGesture(PipTouchGesture gesture) { mGesture = gesture; } @@ -322,7 +327,8 @@ public class PipTouchHandler { // Only show the menu if the user isn't currently interacting with the PiP if (!mTouchState.isUserInteracting()) { mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), - false /* allowMenuTimeout */, willResizeMenu()); + false /* allowMenuTimeout */, willResizeMenu(), + shouldShowResizeHandle()); } } @@ -358,7 +364,8 @@ public class PipTouchHandler { if (mShowPipMenuOnAnimationEnd) { mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, false /* willResizeMenu */); + true /* allowMenuTimeout */, false /* willResizeMenu */, + shouldShowResizeHandle()); mShowPipMenuOnAnimationEnd = false; } } @@ -565,7 +572,8 @@ public class PipTouchHandler { private void onAccessibilityShowMenu() { mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, willResizeMenu()); + true /* allowMenuTimeout */, willResizeMenu(), + shouldShowResizeHandle()); } private boolean handleTouchEvent(InputEvent inputEvent) { @@ -641,7 +649,8 @@ public class PipTouchHandler { // Let's not enable menu show/hide for a11y services. if (!mAccessibilityManager.isTouchExplorationEnabled()) { mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), - false /* allowMenuTimeout */, false /* willResizeMenu */); + false /* allowMenuTimeout */, false /* willResizeMenu */, + shouldShowResizeHandle()); } case MotionEvent.ACTION_HOVER_MOVE: { if (!shouldDeliverToMenu && !mSendingHoverAccessibilityEvents) { @@ -904,7 +913,8 @@ public class PipTouchHandler { // If the menu is still visible, then just poke the menu so that // it will timeout after the user stops touching it mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, willResizeMenu()); + true /* allowMenuTimeout */, willResizeMenu(), + shouldShowResizeHandle()); } mShouldHideMenuAfterFling = mMenuState == MENU_STATE_NONE; @@ -921,7 +931,8 @@ public class PipTouchHandler { // User has stalled long enough for this not to be a drag or a double tap, just // expand the menu mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), - true /* allowMenuTimeout */, willResizeMenu()); + true /* allowMenuTimeout */, willResizeMenu(), + shouldShowResizeHandle()); } else { // Next touch event _may_ be the second tap for the double-tap, schedule a // fallback runnable to trigger the menu if no touch event occurs before the diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java index dc286c1c2de5..4be0c157de8e 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java @@ -318,6 +318,14 @@ public class PipTouchState { return -1; } + /** + * Removes the timeout callback if it's in queue. + */ + public void removeDoubleTapTimeoutCallback() { + mIsWaitingForDoubleTap = false; + mHandler.removeCallbacks(mDoubleTapTimeoutCallback); + } + void addMovementToVelocityTracker(MotionEvent event) { if (mVelocityTracker == null) { return; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java index bc3c33d68b67..e88ce5a96f87 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java @@ -331,7 +331,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { int requestCode = mContext.getUserId(); // Create a edit action - PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode, + PendingIntent editAction = PendingIntent.getBroadcast(context, requestCode, new Intent(context, GlobalScreenshot.ActionProxyReceiver.class) .putExtra(GlobalScreenshot.EXTRA_ACTION_INTENT, editIntent) .putExtra(GlobalScreenshot.EXTRA_CANCEL_NOTIFICATION, @@ -341,7 +341,7 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { mSmartActionsEnabled) .setAction(Intent.ACTION_EDIT) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND), - PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM); + PendingIntent.FLAG_CANCEL_CURRENT); Notification.Action.Builder editActionBuilder = new Notification.Action.Builder( Icon.createWithResource(r, R.drawable.ic_screenshot_edit), r.getString(com.android.internal.R.string.screenshot_edit), editAction); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 88f148b00cdc..6d2cc6b08bc4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -121,14 +121,14 @@ constructor( } override fun onInterceptTouchEvent(event: MotionEvent): Boolean { - return maybeStartExpansion(event) + return canHandleMotionEvent() && startExpansion(event) } - private fun maybeStartExpansion(event: MotionEvent): Boolean { - if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded || - bouncerShowing) { - return false - } + private fun canHandleMotionEvent(): Boolean { + return wakeUpCoordinator.canShowPulsingHuns && !qsExpanded && !bouncerShowing + } + + private fun startExpansion(event: MotionEvent): Boolean { if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain() } @@ -177,8 +177,12 @@ constructor( } override fun onTouchEvent(event: MotionEvent): Boolean { - if (!isExpanding) { - return maybeStartExpansion(event) + if (!canHandleMotionEvent()) { + return false + } + + if (!isExpanding || event.actionMasked == MotionEvent.ACTION_DOWN) { + return startExpansion(event) } velocityTracker!!.addMovement(event) val y = event.y diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt index 53ec57090321..fc6c2be1ce9a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -45,8 +45,8 @@ class ConversationNotificationProcessor @Inject constructor( Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL entry.ranking.shortcutInfo?.let { shortcutInfo -> messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo) - shortcutInfo.shortLabel?.let { shortLabel -> - messagingStyle.conversationTitle = shortLabel + shortcutInfo.label?.let { label -> + messagingStyle.conversationTitle = label } } messagingStyle.unreadMessageCount = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java index 1c2a00ed601a..5794f73a98f4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationChannelHelper.java @@ -67,14 +67,14 @@ public class NotificationChannelHelper { return channel; } - private static String getName(NotificationEntry entry) { - if (entry.getRanking().getShortcutInfo().getShortLabel() != null) { - return entry.getRanking().getShortcutInfo().getShortLabel().toString(); + private static CharSequence getName(NotificationEntry entry) { + if (entry.getRanking().getShortcutInfo().getLabel() != null) { + return entry.getRanking().getShortcutInfo().getLabel().toString(); } Bundle extras = entry.getSbn().getNotification().extras; - String nameString = extras.getString(Notification.EXTRA_CONVERSATION_TITLE); + CharSequence nameString = extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE); if (TextUtils.isEmpty(nameString)) { - nameString = extras.getString(Notification.EXTRA_TITLE); + nameString = extras.getCharSequence(Notification.EXTRA_TITLE); } if (TextUtils.isEmpty(nameString)) { nameString = "fallback"; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt index 2fbd3ee0094a..d32d09dff630 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubNotificationListener.kt @@ -220,9 +220,9 @@ class PeopleHubDataSourceImpl @Inject constructor( } val clickRunnable = Runnable { notificationListener.unsnoozeNotification(key) } val extras = sbn.notification.extras - val name = ranking.shortcutInfo?.shortLabel - ?: extras.getString(Notification.EXTRA_CONVERSATION_TITLE) - ?: extras.getString(Notification.EXTRA_TITLE) + val name = ranking.shortcutInfo?.label + ?: extras.getCharSequence(Notification.EXTRA_CONVERSATION_TITLE) + ?: extras.getCharSequence(Notification.EXTRA_TITLE) ?: return null val drawable = ranking.getIcon(iconFactory, sbn) ?: iconFactory.getConversationDrawable( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java index 0e8c1b78ae6a..8bcdbfef3240 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java @@ -113,16 +113,6 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa } }; - private TaskStackChangeListener mTaskStackChangeListener = new TaskStackChangeListener() { - @Override - public void onRecentTaskListFrozenChanged(boolean frozen) { - if (!frozen) { - mStartingQuickstepRotation = -1; - mDisabledForQuickstep = false; - } - } - }; - private final ContentObserver mFixedRotationObserver = new ContentObserver( new Handler(Looper.getMainLooper())) { @Override @@ -287,12 +277,8 @@ public class EdgeBackGestureHandler extends CurrentUserTracker implements Displa private void setRotationCallbacks(boolean enable) { if (enable) { - ActivityManagerWrapper.getInstance().registerTaskStackListener( - mTaskStackChangeListener); mOverviewProxyService.addCallback(mQuickSwitchListener); } else { - ActivityManagerWrapper.getInstance().unregisterTaskStackListener( - mTaskStackChangeListener); mOverviewProxyService.removeCallback(mQuickSwitchListener); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index b2aa769f1bff..54511c775fda 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -305,14 +305,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } }; - private TaskStackChangeListener mTasksFrozenListener = new TaskStackChangeListener() { - @Override - public void onRecentTaskListFrozenChanged(boolean frozen) { - mFrozenTasks = frozen; - orientSecondaryHomeHandle(); - } - }; - private NavigationBarTransitions.DarkIntensityListener mOrientationHandleIntensityListener = new NavigationBarTransitions.DarkIntensityListener() { @Override @@ -510,7 +502,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } initSecondaryHomeHandleForRotation(); - ActivityManagerWrapper.getInstance().registerTaskStackListener(mTasksFrozenListener); } @Override @@ -527,7 +518,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback } mOverviewProxyService.removeCallback(mOverviewProxyListener); mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver); - ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTasksFrozenListener); if (mOrientationHandle != null) { resetSecondaryHandle(); getContext().getSystemService(DisplayManager.class).unregisterDisplayListener(this); @@ -594,7 +584,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback return; } - if (!mFrozenTasks) { + if (mStartingQuickSwitchRotation == -1) { resetSecondaryHandle(); } else { int deltaRotation = deltaRotation(mCurrentRotation, mStartingQuickSwitchRotation); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 35c33aec8d0f..999e636b4bae 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -38,6 +38,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricSourceType; +import android.os.Bundle; import android.os.PowerManager; import android.os.SystemClock; import android.util.Log; @@ -51,6 +52,7 @@ import android.view.ViewPropertyAnimator; import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.TextView; @@ -244,6 +246,7 @@ public class NotificationPanelViewController extends PanelViewController { private final KeyguardUpdateMonitor mUpdateMonitor; private final ConversationNotificationManager mConversationNotificationManager; private final MediaHierarchyManager mMediaHierarchyManager; + private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -439,6 +442,26 @@ public class NotificationPanelViewController extends PanelViewController { private int mOldLayoutDirection; + private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP); + } + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle args) { + if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.getId() + || action + == AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP.getId()) { + mStatusBarKeyguardViewManager.showBouncer(true); + return true; + } + return super.performAccessibilityAction(host, action, args); + } + }; + @Inject public NotificationPanelViewController(NotificationPanelView view, InjectionInflationController injectionInflationController, @@ -459,7 +482,8 @@ public class NotificationPanelViewController extends PanelViewController { FlingAnimationUtils.Builder flingAnimationUtilsBuilder, StatusBarTouchableRegionManager statusBarTouchableRegionManager, ConversationNotificationManager conversationNotificationManager, - MediaHierarchyManager mediaHierarchyManager) { + MediaHierarchyManager mediaHierarchyManager, + StatusBarKeyguardViewManager statusBarKeyguardViewManager) { super(view, falsingManager, dozeLog, keyguardStateController, (SysuiStatusBarStateController) statusBarStateController, vibratorHelper, latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager); @@ -470,6 +494,7 @@ public class NotificationPanelViewController extends PanelViewController { mConfigurationController = configurationController; mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; mMediaHierarchyManager = mediaHierarchyManager; + mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; mView.setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; mFalsingManager = falsingManager; @@ -583,6 +608,8 @@ public class NotificationPanelViewController extends PanelViewController { mOldLayoutDirection = layoutDirection; } }); + + mView.setAccessibilityDelegate(mAccessibilityDelegate); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java index cb40d7752f53..3bd33ccca911 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java @@ -38,6 +38,7 @@ import androidx.annotation.VisibleForTesting; import com.android.systemui.BootCompleteCache; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.util.Utils; import java.util.ArrayList; @@ -64,16 +65,16 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio private boolean mAreActiveLocationRequests; - private ArrayList<LocationChangeCallback> mSettingsChangeCallbacks = - new ArrayList<LocationChangeCallback>(); - private final H mHandler = new H(); + private final H mHandler; @Inject - public LocationControllerImpl(Context context, @Background Looper bgLooper, - BroadcastDispatcher broadcastDispatcher, BootCompleteCache bootCompleteCache) { + public LocationControllerImpl(Context context, @Main Looper mainLooper, + @Background Looper bgLooper, BroadcastDispatcher broadcastDispatcher, + BootCompleteCache bootCompleteCache) { mContext = context; mBroadcastDispatcher = broadcastDispatcher; mBootCompleteCache = bootCompleteCache; + mHandler = new H(mainLooper); // Register to listen for changes in location settings. IntentFilter filter = new IntentFilter(); @@ -94,12 +95,12 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio * Add a callback to listen for changes in location settings. */ public void addCallback(LocationChangeCallback cb) { - mSettingsChangeCallbacks.add(cb); + mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget(); mHandler.sendEmptyMessage(H.MSG_LOCATION_SETTINGS_CHANGED); } public void removeCallback(LocationChangeCallback cb) { - mSettingsChangeCallbacks.remove(cb); + mHandler.obtainMessage(H.MSG_REMOVE_CALLBACK, cb).sendToTarget(); } /** @@ -208,6 +209,14 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio private final class H extends Handler { private static final int MSG_LOCATION_SETTINGS_CHANGED = 1; private static final int MSG_LOCATION_ACTIVE_CHANGED = 2; + private static final int MSG_ADD_CALLBACK = 3; + private static final int MSG_REMOVE_CALLBACK = 4; + + private ArrayList<LocationChangeCallback> mSettingsChangeCallbacks = new ArrayList<>(); + + H(Looper looper) { + super(looper); + } @Override public void handleMessage(Message msg) { @@ -218,6 +227,13 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio case MSG_LOCATION_ACTIVE_CHANGED: locationActiveChanged(); break; + case MSG_ADD_CALLBACK: + mSettingsChangeCallbacks.add((LocationChangeCallback) msg.obj); + break; + case MSG_REMOVE_CALLBACK: + mSettingsChangeCallbacks.remove((LocationChangeCallback) msg.obj); + break; + } } diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java index c66f07dd4f1e..083c2439aa87 100644 --- a/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java +++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayController.java @@ -134,6 +134,39 @@ public class DisplayController { } }); } + + @Override + public void onFixedRotationStarted(int displayId, int newRotation) { + mHandler.post(() -> { + synchronized (mDisplays) { + if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { + Slog.w(TAG, "Skipping onFixedRotationStarted on unknown" + + " display, displayId=" + displayId); + return; + } + for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) { + mDisplayChangedListeners.get(i).onFixedRotationStarted( + displayId, newRotation); + } + } + }); + } + + @Override + public void onFixedRotationFinished(int displayId) { + mHandler.post(() -> { + synchronized (mDisplays) { + if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { + Slog.w(TAG, "Skipping onFixedRotationFinished on unknown" + + " display, displayId=" + displayId); + return; + } + for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) { + mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId); + } + } + }); + } }; @Inject @@ -232,5 +265,15 @@ public class DisplayController { * Called when a display is removed. */ default void onDisplayRemoved(int displayId) {} + + /** + * Called when fixed rotation on a display is started. + */ + default void onFixedRotationStarted(int displayId, int newRotation) {} + + /** + * Called when fixed rotation on a display is finished. + */ + default void onFixedRotationFinished(int displayId) {} } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java index ec6d3e9d0dff..6a1486382eac 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java @@ -49,11 +49,13 @@ public class ExpandedAnimationControllerTest extends PhysicsAnimationLayoutTestC private int mOrientation = Configuration.ORIENTATION_PORTRAIT; private float mLauncherGridDiff = 30f; + private Runnable mOnBubbleAnimatedOutAction = Mockito.mock(Runnable.class); + @Spy private ExpandedAnimationController mExpandedController = new ExpandedAnimationController( new Point(mDisplayWidth, mDisplayHeight) /* displaySize */, - mExpandedViewPadding, mOrientation); + mExpandedViewPadding, mOrientation, mOnBubbleAnimatedOutAction); private int mStackOffset; private float mBubblePaddingTop; diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java index b1ac022dbe9c..cc62a2f36392 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java @@ -40,6 +40,7 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -66,7 +67,7 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase public int getAsInt() { return mLayout.getChildCount(); } - })); + }, Mockito.mock(Runnable.class))); mLayout.setActiveController(mStackController); addOneMoreThanBubbleLimitBubbles(); mStackOffset = mLayout.getResources().getDimensionPixelSize(R.dimen.bubble_stack_offset); @@ -303,8 +304,9 @@ public class StackAnimationControllerTest extends PhysicsAnimationLayoutTestCase private class TestableStackController extends StackAnimationController { TestableStackController( FloatingContentCoordinator floatingContentCoordinator, - IntSupplier bubbleCountSupplier) { - super(floatingContentCoordinator, bubbleCountSupplier); + IntSupplier bubbleCountSupplier, + Runnable onBubbleAnimatedOutAction) { + super(floatingContentCoordinator, bubbleCountSupplier, onBubbleAnimatedOutAction); } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index e8fb41a18ce9..4d30500bad45 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -98,6 +98,8 @@ public class MediaControlPanelTest : SysuiTestCase() { private lateinit var action4: ImageButton private lateinit var session: MediaSession + private val device = MediaDeviceData(true, null, DEVICE_NAME) + private val disabledDevice = MediaDeviceData(false, null, null) @Before fun setUp() { @@ -181,7 +183,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Test fun bindWhenUnattached() { val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), - emptyList(), PACKAGE, null, null, MediaDeviceData(null, DEVICE_NAME)) + emptyList(), PACKAGE, null, null, device) player.bind(state) assertThat(player.isPlaying()).isFalse() } @@ -190,8 +192,7 @@ public class MediaControlPanelTest : SysuiTestCase() { fun bindText() { player.attach(holder) val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), - emptyList(), PACKAGE, session.getSessionToken(), null, - MediaDeviceData(null, DEVICE_NAME)) + emptyList(), PACKAGE, session.getSessionToken(), null, device) player.bind(state) assertThat(appName.getText()).isEqualTo(APP) assertThat(titleText.getText()).isEqualTo(TITLE) @@ -202,9 +203,40 @@ public class MediaControlPanelTest : SysuiTestCase() { fun bindBackgroundColor() { player.attach(holder) val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), - emptyList(), PACKAGE, session.getSessionToken(), null, - MediaDeviceData(null, DEVICE_NAME)) + emptyList(), PACKAGE, session.getSessionToken(), null, device) player.bind(state) assertThat(background.getBackgroundTintList()).isEqualTo(ColorStateList.valueOf(BG_COLOR)) } + + @Test + fun bindDevice() { + player.attach(holder) + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, device) + player.bind(state) + assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME) + assertThat(seamless.isEnabled()).isTrue() + } + + @Test + fun bindDisabledDevice() { + player.attach(holder) + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, disabledDevice) + player.bind(state) + assertThat(seamless.isEnabled()).isFalse() + assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString( + R.string.media_seamless_remote_device)) + } + + @Test + fun bindNullDevice() { + player.attach(holder) + val state = MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(), + emptyList(), PACKAGE, session.getSessionToken(), null, null) + player.bind(state) + assertThat(seamless.isEnabled()).isTrue() + assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString( + com.android.internal.R.string.ext_media_seamless_action)) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java index 64a180f8aaab..aa889a64c1b8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java @@ -80,7 +80,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase { mMediaData = new MediaData(true, BG_COLOR, APP, null, ARTIST, TITLE, null, new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null); - mDeviceData = new MediaDeviceData(null, DEVICE_NAME); + mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt index ac6b5f6bca66..7b80a6ea94a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt @@ -18,6 +18,8 @@ package com.android.systemui.media import android.app.Notification import android.media.MediaMetadata +import android.media.MediaRouter2Manager +import android.media.RoutingSessionInfo import android.media.session.MediaSession import android.media.session.PlaybackState import android.os.Process @@ -36,16 +38,18 @@ import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.any -import org.mockito.Mockito.mock import org.mockito.Mockito.never +import org.mockito.Mockito.reset import org.mockito.Mockito.verify import org.mockito.Mockito.`when` as whenever +import org.mockito.junit.MockitoJUnit private const val KEY = "TEST_KEY" private const val PACKAGE = "PKG" @@ -62,34 +66,34 @@ private fun <T> eq(value: T): T = Mockito.eq(value) ?: value public class MediaDeviceManagerTest : SysuiTestCase() { private lateinit var manager: MediaDeviceManager - @Mock private lateinit var lmmFactory: LocalMediaManagerFactory @Mock private lateinit var lmm: LocalMediaManager + @Mock private lateinit var mr2: MediaRouter2Manager @Mock private lateinit var featureFlag: MediaFeatureFlag private lateinit var fakeExecutor: FakeExecutor - + @Mock private lateinit var listener: MediaDeviceManager.Listener @Mock private lateinit var device: MediaDevice + @Mock private lateinit var route: RoutingSessionInfo private lateinit var session: MediaSession private lateinit var metadataBuilder: MediaMetadata.Builder private lateinit var playbackBuilder: PlaybackState.Builder private lateinit var notifBuilder: Notification.Builder private lateinit var sbn: StatusBarNotification + @JvmField @Rule val mockito = MockitoJUnit.rule() @Before - fun setup() { - lmmFactory = mock(LocalMediaManagerFactory::class.java) - lmm = mock(LocalMediaManager::class.java) - device = mock(MediaDevice::class.java) + fun setUp() { + fakeExecutor = FakeExecutor(FakeSystemClock()) + manager = MediaDeviceManager(context, lmmFactory, mr2, featureFlag, fakeExecutor) + manager.addListener(listener) + + // Configure mocks. whenever(device.name).thenReturn(DEVICE_NAME) whenever(lmmFactory.create(PACKAGE)).thenReturn(lmm) whenever(lmm.getCurrentConnectedDevice()).thenReturn(device) - featureFlag = mock(MediaFeatureFlag::class.java) + whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(route) whenever(featureFlag.enabled).thenReturn(true) - fakeExecutor = FakeExecutor(FakeSystemClock()) - - manager = MediaDeviceManager(context, lmmFactory, featureFlag, fakeExecutor) - // Create a media sesssion and notification for testing. metadataBuilder = MediaMetadata.Builder().apply { putString(MediaMetadata.METADATA_KEY_ARTIST, SESSION_ARTIST) @@ -145,51 +149,106 @@ public class MediaDeviceManagerTest : SysuiTestCase() { } @Test + fun deviceEventOnAddNotification() { + // WHEN a notification is added + manager.onNotificationAdded(KEY, sbn) + val deviceCallback = captureCallback() + // THEN the update is dispatched to the listener + val data = captureDeviceData(KEY) + assertThat(data.enabled).isTrue() + assertThat(data.name).isEqualTo(DEVICE_NAME) + } + + @Test fun deviceListUpdate() { - val listener = mock(MediaDeviceManager.Listener::class.java) - manager.addListener(listener) manager.onNotificationAdded(KEY, sbn) val deviceCallback = captureCallback() // WHEN the device list changes deviceCallback.onDeviceListUpdate(mutableListOf(device)) assertThat(fakeExecutor.runAllReady()).isEqualTo(1) // THEN the update is dispatched to the listener - val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) - verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture()) - val data = captor.getValue() + val data = captureDeviceData(KEY) + assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(DEVICE_NAME) } @Test fun selectedDeviceStateChanged() { - val listener = mock(MediaDeviceManager.Listener::class.java) - manager.addListener(listener) manager.onNotificationAdded(KEY, sbn) val deviceCallback = captureCallback() // WHEN the selected device changes state deviceCallback.onSelectedDeviceStateChanged(device, 1) assertThat(fakeExecutor.runAllReady()).isEqualTo(1) // THEN the update is dispatched to the listener - val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) - verify(listener).onMediaDeviceChanged(eq(KEY), captor.capture()) - val data = captor.getValue() + val data = captureDeviceData(KEY) + assertThat(data.enabled).isTrue() assertThat(data.name).isEqualTo(DEVICE_NAME) } @Test fun listenerReceivesKeyRemoved() { manager.onNotificationAdded(KEY, sbn) - val listener = mock(MediaDeviceManager.Listener::class.java) - manager.addListener(listener) // WHEN the notification is removed manager.onNotificationRemoved(KEY) // THEN the listener receives key removed event verify(listener).onKeyRemoved(eq(KEY)) } + @Test + fun deviceDisabledWhenMR2ReturnsNullRouteInfo() { + // GIVEN that MR2Manager returns null for routing session + whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) + // WHEN a notification is added + manager.onNotificationAdded(KEY, sbn) + // THEN the device is disabled + val data = captureDeviceData(KEY) + assertThat(data.enabled).isFalse() + assertThat(data.name).isNull() + } + + @Test + fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceChanged() { + // GIVEN a notif is added + manager.onNotificationAdded(KEY, sbn) + reset(listener) + // AND MR2Manager returns null for routing session + whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) + // WHEN the selected device changes state + val deviceCallback = captureCallback() + deviceCallback.onSelectedDeviceStateChanged(device, 1) + fakeExecutor.runAllReady() + // THEN the device is disabled + val data = captureDeviceData(KEY) + assertThat(data.enabled).isFalse() + assertThat(data.name).isNull() + } + + @Test + fun deviceDisabledWhenMR2ReturnsNullRouteInfoOnDeviceListUpdate() { + // GIVEN a notif is added + manager.onNotificationAdded(KEY, sbn) + reset(listener) + // GIVEN that MR2Manager returns null for routing session + whenever(mr2.getRoutingSessionForMediaController(any())).thenReturn(null) + // WHEN the selected device changes state + val deviceCallback = captureCallback() + deviceCallback.onDeviceListUpdate(mutableListOf(device)) + fakeExecutor.runAllReady() + // THEN the device is disabled + val data = captureDeviceData(KEY) + assertThat(data.enabled).isFalse() + assertThat(data.name).isNull() + } + fun captureCallback(): LocalMediaManager.DeviceCallback { val captor = ArgumentCaptor.forClass(LocalMediaManager.DeviceCallback::class.java) verify(lmm).registerCallback(captor.capture()) return captor.getValue() } + + fun captureDeviceData(key: String): MediaDeviceData { + val captor = ArgumentCaptor.forClass(MediaDeviceData::class.java) + verify(listener).onMediaDeviceChanged(eq(key), captor.capture()) + return captor.getValue() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java index dbf40e467c95..4b21ef294db8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java @@ -193,7 +193,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase { when(mMockPackageManager.getPackageInfo(eq("android"), anyInt())) .thenReturn(packageInfo); - when(mShortcutInfo.getShortLabel()).thenReturn("Convo name"); + when(mShortcutInfo.getLabel()).thenReturn("Convo name"); List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts); when(mIconFactory.getConversationDrawable( diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index b5663d5dd19e..c2d218140803 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -43,6 +43,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import androidx.test.filters.SmallTest; @@ -80,11 +81,13 @@ import com.android.systemui.util.InjectionInflationController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; +import java.util.List; import java.util.function.Consumer; @SmallTest @@ -176,9 +179,12 @@ public class NotificationPanelViewTest extends SysuiTestCase { private MediaHierarchyManager mMediaHiearchyManager; @Mock private ConversationNotificationManager mConversationNotificationManager; + @Mock + private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder; private NotificationPanelViewController mNotificationPanelViewController; + private View.AccessibilityDelegate mAccessibiltyDelegate; @Before public void setup() { @@ -231,11 +237,18 @@ public class NotificationPanelViewTest extends SysuiTestCase { mLatencyTracker, mPowerManager, mAccessibilityManager, 0, mUpdateMonitor, mMetricsLogger, mActivityManager, mZenModeController, mConfigurationController, mFlingAnimationUtilsBuilder, mStatusBarTouchableRegionManager, - mConversationNotificationManager, mMediaHiearchyManager); + mConversationNotificationManager, mMediaHiearchyManager, + mStatusBarKeyguardViewManager); mNotificationPanelViewController.initDependencies(mStatusBar, mGroupManager, mNotificationShelf, mNotificationAreaController, mScrimController); mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager); mNotificationPanelViewController.setBar(mPanelBar); + + ArgumentCaptor<View.AccessibilityDelegate> accessibilityDelegateArgumentCaptor = + ArgumentCaptor.forClass(View.AccessibilityDelegate.class); + verify(mView) + .setAccessibilityDelegate(accessibilityDelegateArgumentCaptor.capture()); + mAccessibiltyDelegate = accessibilityDelegateArgumentCaptor.getValue(); } @Test @@ -305,6 +318,39 @@ public class NotificationPanelViewTest extends SysuiTestCase { verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE); } + @Test + public void testA11y_initializeNode() { + AccessibilityNodeInfo nodeInfo = new AccessibilityNodeInfo(); + mAccessibiltyDelegate.onInitializeAccessibilityNodeInfo(mView, nodeInfo); + + List<AccessibilityNodeInfo.AccessibilityAction> actionList = nodeInfo.getActionList(); + assertThat(actionList).containsAllIn( + new AccessibilityNodeInfo.AccessibilityAction[] { + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD, + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP} + ); + } + + @Test + public void testA11y_scrollForward() { + mAccessibiltyDelegate.performAccessibilityAction( + mView, + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD.getId(), + null); + + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } + + @Test + public void testA11y_scrollUp() { + mAccessibiltyDelegate.performAccessibilityAction( + mView, + AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_UP.getId(), + null); + + verify(mStatusBarKeyguardViewManager).showBouncer(true); + } + private void onTouchEvent(MotionEvent ev) { mTouchHandler.onTouch(mView, ev); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java index 81c375a2480b..5ce209b1f249 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java @@ -14,8 +14,11 @@ package com.android.systemui.statusbar.policy; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Intent; @@ -32,7 +35,6 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,17 +44,19 @@ import org.junit.runner.RunWith; public class LocationControllerImplTest extends SysuiTestCase { private LocationControllerImpl mLocationController; + private TestableLooper mTestableLooper; @Before public void setup() { + mTestableLooper = TestableLooper.get(this); mLocationController = spy(new LocationControllerImpl(mContext, - TestableLooper.get(this).getLooper(), + mTestableLooper.getLooper(), + mTestableLooper.getLooper(), mock(BroadcastDispatcher.class), mock(BootCompleteCache.class))); } @Test - @Ignore("flaky") public void testRemoveSelfActive_DoesNotCrash() { LocationController.LocationChangeCallback callback = new LocationChangeCallback() { @Override @@ -70,11 +74,10 @@ public class LocationControllerImplTest extends SysuiTestCase { mLocationController.onReceive(mContext, new Intent( LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION)); - TestableLooper.get(this).processAllMessages(); + mTestableLooper.processAllMessages(); } @Test - @Ignore("flaky") public void testRemoveSelfSettings_DoesNotCrash() { LocationController.LocationChangeCallback callback = new LocationChangeCallback() { @Override @@ -85,6 +88,47 @@ public class LocationControllerImplTest extends SysuiTestCase { mLocationController.addCallback(callback); mLocationController.addCallback(mock(LocationChangeCallback.class)); - TestableLooper.get(this).processAllMessages(); + mTestableLooper.processAllMessages(); + } + + @Test + public void testAddCallback_notifiedImmediately() { + LocationChangeCallback callback = mock(LocationChangeCallback.class); + + mLocationController.addCallback(callback); + + mTestableLooper.processAllMessages(); + + verify(callback).onLocationSettingsChanged(anyBoolean()); + } + + @Test + public void testCallbackNotified() { + LocationChangeCallback callback = mock(LocationChangeCallback.class); + + mLocationController.addCallback(callback); + mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION)); + + mTestableLooper.processAllMessages(); + + verify(callback, times(2)).onLocationSettingsChanged(anyBoolean()); + } + + @Test + public void testCallbackRemoved() { + LocationChangeCallback callback = mock(LocationChangeCallback.class); + + mLocationController.addCallback(callback); + mTestableLooper.processAllMessages(); + + verify(callback).onLocationSettingsChanged(anyBoolean()); + mLocationController.removeCallback(callback); + + mLocationController.onReceive(mContext, new Intent(LocationManager.MODE_CHANGED_ACTION)); + + mTestableLooper.processAllMessages(); + + // No new callbacks + verify(callback).onLocationSettingsChanged(anyBoolean()); } } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index b3867a35dba5..07bb3356aec0 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -51,6 +51,7 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.database.ContentObserver; @@ -2934,11 +2935,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub public class AccessibilityDisplayListener implements DisplayManager.DisplayListener { private final DisplayManager mDisplayManager; private final ArrayList<Display> mDisplaysList = new ArrayList<>(); + private int mSystemUiUid = 0; AccessibilityDisplayListener(Context context, MainHandler handler) { mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager.registerDisplayListener(this, handler); initializeDisplayList(); + + final PackageManagerInternal pm = + LocalServices.getService(PackageManagerInternal.class); + if (pm != null) { + mSystemUiUid = pm.getPackageUid(pm.getSystemUiServiceComponent().getPackageName(), + PackageManager.MATCH_SYSTEM_ONLY, mCurrentUserId); + } } ArrayList<Display> getValidDisplayList() { @@ -3034,8 +3043,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub } // Private virtual displays are created by the ap and is not allowed to access by other // aps. We assume we could ignore them. + // The exceptional case is for bubbles. Because the bubbles use the activityView, and + // the virtual display of the activityView is private, so if the owner UID of the + // private virtual display is the one of system ui which creates the virtual display of + // bubbles, then this private virtual display should track the windows. if (display.getType() == Display.TYPE_VIRTUAL - && (display.getFlags() & Display.FLAG_PRIVATE) != 0) { + && (display.getFlags() & Display.FLAG_PRIVATE) != 0 + && display.getOwnerUid() != mSystemUiUid) { return false; } return true; diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java index a3b5a3e2dcf9..6d0f069e51ac 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/GestureManifold.java @@ -295,7 +295,7 @@ class GestureManifold implements GestureMatcher.StateChangeListener { mListener.onGestureStarted(); } } else if (state == GestureMatcher.STATE_GESTURE_COMPLETED) { - onGestureCompleted(gestureId); + onGestureCompleted(gestureId, event, rawEvent, policyFlags); } else if (state == GestureMatcher.STATE_GESTURE_CANCELED && mState.isGestureDetecting()) { // We only want to call the cancelation callback if there are no other pending // detectors. @@ -311,8 +311,8 @@ class GestureManifold implements GestureMatcher.StateChangeListener { } } - private void onGestureCompleted(int gestureId) { - MotionEvent event = mState.getLastReceivedEvent(); + private void onGestureCompleted( + int gestureId, MotionEvent event, MotionEvent rawEvent, int policyFlags) { // Note that gestures that complete immediately call clear() from onMotionEvent. // Gestures that complete on a delay call clear() here. switch (gestureId) { diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java index e5340f10dc4c..642a841257bf 100644 --- a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java +++ b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerMultiTap.java @@ -197,6 +197,7 @@ class MultiFingerMultiTap extends GestureMatcher { if (getState() == STATE_GESTURE_STARTED || getState() == STATE_CLEAR) { // Needs more fingers lifted within the tap timeout // after reaching the target number of fingers are down. + cancelAfterTapTimeout(event, rawEvent, policyFlags); } else { cancelGesture(event, rawEvent, policyFlags); } diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java index 3dd2433ac2bd..23bb9d63d6fa 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java @@ -127,6 +127,22 @@ final class AutofillInlineSessionController { } /** + * Clear the locally cached inline fill UI, but don't clear the suggestion in the IME. + * + * <p>This is called to invalid the locally cached inline suggestions so we don't resend them + * to the IME, while assuming that the IME will clean up suggestion on their own when the input + * connection is finished. We don't send an empty response to IME so that it doesn't cause UI + * flicker on the IME side if it arrives before the input view is finished on the IME. + */ + @GuardedBy("mLock") + void resetInlineFillUiLocked() { + mInlineFillUi = null; + if (mSession != null) { + mSession.resetInlineFillUiLocked(); + } + } + + /** * Updates the inline fill UI with the filter text. It'll send updated inline suggestions to * the IME. */ diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java index 1a3baba1ff19..687b75a8b949 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java +++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java @@ -191,6 +191,16 @@ final class AutofillInlineSuggestionsRequestSession { } /** + * Clear the locally cached inline fill UI, but don't clear the suggestion in IME. + * + * See also {@link AutofillInlineSessionController#resetInlineFillUiLocked()} + */ + @GuardedBy("mLock") + void resetInlineFillUiLocked() { + mInlineFillUi = null; + } + + /** * Optionally sends inline response to the IME, depending on the current state. */ @GuardedBy("mLock") diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 1d3ab9b7e24b..558acfa3ed19 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2581,6 +2581,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (sVerbose) Slog.v(TAG, "Exiting view " + id); mUi.hideFillUi(this); hideAugmentedAutofillLocked(viewState); + // We don't send an empty response to IME so that it doesn't cause UI flicker + // on the IME side if it arrives before the input view is finished on the IME. + mInlineSessionController.resetInlineFillUiLocked(); mCurrentViewId = null; } break; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 119715456f09..7c61ba2e7adb 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -3087,23 +3087,7 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void notifyDataStallSuspected(DataStallReportParcelable p) { - final PersistableBundle extras = new PersistableBundle(); - switch (p.detectionMethod) { - case DETECTION_METHOD_DNS_EVENTS: - extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); - break; - case DETECTION_METHOD_TCP_METRICS: - extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); - extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, - p.tcpMetricsCollectionPeriodMillis); - break; - default: - log("Unknown data stall detection method, ignoring: " + p.detectionMethod); - return; - } - - proxyDataStallToConnectivityDiagnosticsHandler( - p.detectionMethod, mNetId, p.timestampMillis, extras); + ConnectivityService.this.notifyDataStallSuspected(p, mNetId); } @Override @@ -3117,11 +3101,31 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void proxyDataStallToConnectivityDiagnosticsHandler(int detectionMethod, int netId, - long timestampMillis, @NonNull PersistableBundle extras) { + private void notifyDataStallSuspected(DataStallReportParcelable p, int netId) { + final PersistableBundle extras = new PersistableBundle(); + switch (p.detectionMethod) { + case DETECTION_METHOD_DNS_EVENTS: + extras.putInt(KEY_DNS_CONSECUTIVE_TIMEOUTS, p.dnsConsecutiveTimeouts); + break; + case DETECTION_METHOD_TCP_METRICS: + extras.putInt(KEY_TCP_PACKET_FAIL_RATE, p.tcpPacketFailRate); + extras.putInt(KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS, + p.tcpMetricsCollectionPeriodMillis); + break; + default: + // TODO(b/156294356): update for new data stall detection methods + log("Unknown data stall detection method, ignoring: " + p.detectionMethod); + return; + } + + notifyDataStallSuspected(p.detectionMethod, netId, p.timestampMillis, extras); + } + + private void notifyDataStallSuspected(int detectionMethod, int netId, long timestampMillis, + @NonNull PersistableBundle extras) { final Message msg = mConnectivityDiagnosticsHandler.obtainMessage( - ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, - detectionMethod, netId, timestampMillis); + ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED, detectionMethod, netId, + timestampMillis); msg.setData(new Bundle(extras)); // NetworkStateTrackerHandler currently doesn't take any actions based on data @@ -7134,6 +7138,14 @@ public class ConnectivityService extends IConnectivityManager.Stub networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); if (!createNativeNetwork(networkAgent)) return; + if (networkAgent.isVPN()) { + // Initialize the VPN capabilities to their starting values according to the + // underlying networks. This will avoid a spurious callback to + // onCapabilitiesUpdated being sent in updateAllVpnCapabilities below as + // the VPN would switch from its default, blank capabilities to those + // that reflect the capabilities of its underlying networks. + updateAllVpnsCapabilities(); + } networkAgent.created = true; } @@ -8177,7 +8189,6 @@ public class ConnectivityService extends IConnectivityManager.Stub + "creators"); } - proxyDataStallToConnectivityDiagnosticsHandler( - detectionMethod, network.netId, timestampMillis, extras); + notifyDataStallSuspected(detectionMethod, network.netId, timestampMillis, extras); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4ace676eca7e..671733b7cb7a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -299,6 +299,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; @@ -337,7 +338,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.TriFunction; -import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AlarmManagerInternal; import com.android.server.AttributeCache; import com.android.server.DeviceIdleInternal; @@ -823,6 +823,46 @@ public class ActivityManagerService extends IActivityManager.Stub } /** + * While starting activity, WindowManager posts a runnable to DisplayThread to updateOomAdj. + * The latency of the thread switch could cause client app failure when the app is checking + * {@link #isUidActive} before updateOomAdj is done. + * + * Use PendingStartActivityUids to save uid after WindowManager start activity and before + * updateOomAdj is done. + * + * <p>NOTE: This object is protected by its own lock, NOT the global activity manager lock! + */ + final PendingStartActivityUids mPendingStartActivityUidsLocked = new PendingStartActivityUids(); + final class PendingStartActivityUids { + // Key is uid, value is SystemClock.elapsedRealtime() when the key is added. + private final SparseLongArray mPendingUids = new SparseLongArray(); + + void add(int uid) { + if (mPendingUids.indexOfKey(uid) < 0) { + mPendingUids.put(uid, SystemClock.elapsedRealtime()); + } + } + + void delete(int uid) { + if (mPendingUids.indexOfKey(uid) >= 0) { + long delay = SystemClock.elapsedRealtime() - mPendingUids.get(uid); + if (delay >= 1000) { + Slog.wtf(TAG, + "PendingStartActivityUids startActivity to updateOomAdj delay:" + + delay + "ms," + + " uid:" + uid + + " packageName:" + Settings.getPackageNameForUid(mContext, uid)); + } + mPendingUids.delete(uid); + } + } + + boolean isPendingTopUid(int uid) { + return mPendingUids.indexOfKey(uid) >= 0; + } + } + + /** * Puts the process record in the map. * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this * method. @@ -8792,7 +8832,18 @@ public class ActivityManagerService extends IActivityManager.Stub "isUidActive"); } synchronized (this) { - return isUidActiveLocked(uid); + if (isUidActiveLocked(uid)) { + return true; + } + } + + if (mInternal.isPendingTopUid(uid)) { + Slog.wtf(TAG, "PendingStartActivityUids isUidActive false but" + + " isPendingTopUid true, uid:" + uid + + " callingPackage:" + callingPackage); + return true; + } else { + return false; } } @@ -18832,39 +18883,28 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) { - final Object wmLock = mActivityTaskManager.getGlobalLock(); - if (Thread.currentThread().holdsLock(wmLock) - && !Thread.currentThread().holdsLock(ActivityManagerService.this)) { - // We can find ourselves needing to check Uri permissions while already holding the - // WM lock, which means reaching back here for the AM lock would cause an inversion. - // The WM team has requested that we use the strategy below instead of shifting - // where Uri grants are calculated. - synchronized (wmLock) { - final int[] result = new int[1]; - final Message msg = PooledLambda.obtainMessage( - LocalService::checkContentProviderUriPermission, - this, uri, userId, callingUid, modeFlags, wmLock, result); - mHandler.sendMessage(msg); - try { - wmLock.wait(); - } catch (InterruptedException ignore) { - - } - return result[0]; - } - } else { + // We can find ourselves needing to check Uri permissions while + // already holding the WM lock, which means reaching back here for + // the AM lock would cause an inversion. The WM team has requested + // that we use the strategy below instead of shifting where Uri + // grants are calculated. + + // Since we could also arrive here while holding the AM lock, we + // can't always delegate the call through the handler, and we need + // to delicately dance between the deadlocks. + if (Thread.currentThread().holdsLock(ActivityManagerService.this)) { return ActivityManagerService.this.checkContentProviderUriPermission(uri, userId, callingUid, modeFlags); - } - } - - void checkContentProviderUriPermission( - Uri uri, int userId, int callingUid, int modeFlags, Object wmLock, int[] result) { - synchronized (ActivityManagerService.this) { - synchronized (wmLock) { - result[0] = ActivityManagerService.this.checkContentProviderUriPermission( - uri, userId, callingUid, modeFlags); - wmLock.notify(); + } else { + final CompletableFuture<Integer> res = new CompletableFuture<>(); + mHandler.post(() -> { + res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri, + userId, callingUid, modeFlags)); + }); + try { + return res.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); } } } @@ -19694,6 +19734,25 @@ public class ActivityManagerService extends IActivityManager.Stub return uid >= 0 && mDeviceOwnerUid == uid; } } + + @Override + public void updatePendingTopUid(int uid, boolean pending) { + synchronized (mPendingStartActivityUidsLocked) { + if (pending) { + mPendingStartActivityUidsLocked.add(uid); + } else { + mPendingStartActivityUidsLocked.delete(uid); + } + } + + } + + @Override + public boolean isPendingTopUid(int uid) { + synchronized (mPendingStartActivityUidsLocked) { + return mPendingStartActivityUidsLocked.isPendingTopUid(uid); + } + } } long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index c13bb5aff9b9..f7a158a885c6 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -938,6 +938,7 @@ public final class OomAdjuster { mService.mServices.foregroundServiceProcStateChangedLocked(uidRec); } } + mService.mInternal.updatePendingTopUid(uidRec.uid, false); } if (mLocalPowerManager != null) { mLocalPowerManager.finishUidChanges(); diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index fac4a1e95827..ea7059894f38 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -90,7 +90,6 @@ import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; -import android.util.SparseLongArray; import android.util.proto.ProtoOutputStream; import com.android.internal.R; @@ -154,6 +153,15 @@ class UserController implements Handler.Callback { static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 110; static final int START_USER_SWITCH_FG_MSG = 120; + // Message constant to clear {@link UserJourneySession} from {@link mUserIdToUserJourneyMap} if + // the user journey, defined in the UserLifecycleJourneyReported atom for statsd, is not + // complete within {@link USER_JOURNEY_TIMEOUT}. + private static final int CLEAR_USER_JOURNEY_SESSION_MSG = 200; + // Wait time for completing the user journey. If a user journey is not complete within this + // time, the remaining lifecycle events for the journey would not be logged in statsd. + // Timeout set for 90 seconds. + private static final int USER_JOURNEY_TIMEOUT_MS = 90_000; + // UI thread message constants static final int START_USER_SWITCH_UI_MSG = 1000; @@ -194,14 +202,37 @@ class UserController implements Handler.Callback { FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__START_USER; private static final int USER_LIFECYCLE_EVENT_CREATE_USER = FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER; + private static final int USER_LIFECYCLE_EVENT_USER_RUNNING_LOCKED = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__USER_RUNNING_LOCKED; + private static final int USER_LIFECYCLE_EVENT_UNLOCKING_USER = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__UNLOCKING_USER; + private static final int USER_LIFECYCLE_EVENT_UNLOCKED_USER = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__UNLOCKED_USER; @IntDef(prefix = { "USER_LIFECYCLE_EVENT" }, value = { USER_LIFECYCLE_EVENT_UNKNOWN, USER_LIFECYCLE_EVENT_SWITCH_USER, USER_LIFECYCLE_EVENT_START_USER, USER_LIFECYCLE_EVENT_CREATE_USER, + USER_LIFECYCLE_EVENT_USER_RUNNING_LOCKED, + USER_LIFECYCLE_EVENT_UNLOCKING_USER, + USER_LIFECYCLE_EVENT_UNLOCKED_USER, }) @interface UserLifecycleEvent {} + // User lifecyle event state, defined in the UserLifecycleEventOccurred atom for statsd + private static final int USER_LIFECYCLE_EVENT_STATE_BEGIN = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN; + private static final int USER_LIFECYCLE_EVENT_STATE_FINISH = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH; + private static final int USER_LIFECYCLE_EVENT_STATE_NONE = + FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE; + @IntDef(prefix = { "USER_LIFECYCLE_EVENT_STATE" }, value = { + USER_LIFECYCLE_EVENT_STATE_BEGIN, + USER_LIFECYCLE_EVENT_STATE_FINISH, + USER_LIFECYCLE_EVENT_STATE_NONE, + }) + @interface UserLifecycleEventState {} + /** * Maximum number of users we allow to be running at a time, including system user. * @@ -311,11 +342,11 @@ class UserController implements Handler.Callback { private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>(); /** - * A per-user, journey to session id map, used for statsd logging for the + * {@link UserIdInt} to {@link UserJourneySession} mapping used for statsd logging for the * UserLifecycleJourneyReported and UserLifecycleEventOccurred atoms. */ - @GuardedBy("mUserJourneyToSessionIdMap") - private final SparseArray<SparseLongArray> mUserJourneyToSessionIdMap = new SparseArray<>(); + @GuardedBy("mUserIdToUserJourneyMap") + private final SparseArray<UserJourneySession> mUserIdToUserJourneyMap = new SparseArray<>(); UserController(ActivityManagerService service) { this(new Injector(service)); @@ -447,6 +478,8 @@ class UserController implements Handler.Callback { // but we might immediately step into RUNNING below if the user // storage is already unlocked. if (uss.setState(STATE_BOOTING, STATE_RUNNING_LOCKED)) { + logUserLifecycleEvent(userId, USER_LIFECYCLE_EVENT_USER_RUNNING_LOCKED, + USER_LIFECYCLE_EVENT_STATE_NONE); mInjector.getUserManagerInternal().setUserState(userId, uss.state); // Do not report secondary users, runtime restarts or first boot/upgrade if (userId == UserHandle.USER_SYSTEM @@ -503,6 +536,8 @@ class UserController implements Handler.Callback { private boolean finishUserUnlocking(final UserState uss) { final int userId = uss.mHandle.getIdentifier(); EventLog.writeEvent(EventLogTags.UC_FINISH_USER_UNLOCKING, userId); + logUserLifecycleEvent(userId, USER_LIFECYCLE_EVENT_UNLOCKING_USER, + USER_LIFECYCLE_EVENT_STATE_BEGIN); // Only keep marching forward if user is actually unlocked if (!StorageManager.isUserKeyUnlocked(userId)) return false; synchronized (mLock) { @@ -2396,8 +2431,8 @@ class UserController implements Handler.Callback { case START_USER_SWITCH_FG_MSG: logUserJourneyInfo(getUserInfo(getCurrentUserId()), getUserInfo(msg.arg1), USER_JOURNEY_USER_SWITCH_FG); - logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_SWITCH_FG, - USER_LIFECYCLE_EVENT_SWITCH_USER, true); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_SWITCH_USER, + USER_LIFECYCLE_EVENT_STATE_BEGIN); startUserInForeground(msg.arg1); break; case REPORT_USER_SWITCH_MSG: @@ -2420,14 +2455,14 @@ class UserController implements Handler.Callback { BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(msg.arg1), msg.arg1); logUserJourneyInfo(null, getUserInfo(msg.arg1), USER_JOURNEY_USER_START); - logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START, - USER_LIFECYCLE_EVENT_START_USER, true); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_START_USER, + USER_LIFECYCLE_EVENT_STATE_BEGIN); mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(), msg.arg1); - logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START, - USER_LIFECYCLE_EVENT_START_USER, false); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_START_USER, + USER_LIFECYCLE_EVENT_STATE_FINISH); clearSessionId(msg.arg1, USER_JOURNEY_USER_START); break; case USER_UNLOCK_MSG: @@ -2437,10 +2472,17 @@ class UserController implements Handler.Callback { FgThread.getHandler().post(() -> { mInjector.loadUserRecents(userId); }); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKING_USER, + USER_LIFECYCLE_EVENT_STATE_FINISH); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKED_USER, + USER_LIFECYCLE_EVENT_STATE_BEGIN); finishUserUnlocked((UserState) msg.obj); break; case USER_UNLOCKED_MSG: mInjector.getSystemServiceManager().onUserUnlocked(msg.arg1); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKED_USER, + USER_LIFECYCLE_EVENT_STATE_FINISH); + clearSessionId(msg.arg1); break; case USER_CURRENT_MSG: mInjector.batteryStatsServiceNoteEvent( @@ -2458,11 +2500,8 @@ class UserController implements Handler.Callback { case REPORT_USER_SWITCH_COMPLETE_MSG: dispatchUserSwitchComplete(msg.arg1); - final int currentJourney = mUserSwitchUiEnabled ? USER_JOURNEY_USER_SWITCH_UI - : USER_JOURNEY_USER_SWITCH_FG; - logUserLifecycleEvent(msg.arg1, currentJourney, - USER_LIFECYCLE_EVENT_SWITCH_USER, false); - clearSessionId(msg.arg1, currentJourney); + logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_SWITCH_USER, + USER_LIFECYCLE_EVENT_STATE_FINISH); break; case REPORT_LOCKED_BOOT_COMPLETE_MSG: dispatchLockedBootComplete(msg.arg1); @@ -2471,10 +2510,13 @@ class UserController implements Handler.Callback { final Pair<UserInfo, UserInfo> fromToUserPair = (Pair<UserInfo, UserInfo>) msg.obj; logUserJourneyInfo(fromToUserPair.first, fromToUserPair.second, USER_JOURNEY_USER_SWITCH_UI); - logUserLifecycleEvent(fromToUserPair.second.id, USER_JOURNEY_USER_SWITCH_UI, - USER_LIFECYCLE_EVENT_SWITCH_USER, true); + logUserLifecycleEvent(fromToUserPair.second.id, USER_LIFECYCLE_EVENT_SWITCH_USER, + USER_LIFECYCLE_EVENT_STATE_BEGIN); showUserSwitchDialog(fromToUserPair); break; + case CLEAR_USER_JOURNEY_SESSION_MSG: + clearSessionId(msg.arg1); + break; } return false; } @@ -2482,27 +2524,61 @@ class UserController implements Handler.Callback { /** * statsd helper method for logging the start of a user journey via a UserLifecycleEventOccurred * atom given the originating and targeting users for the journey. - * - * Note: these info atoms are currently logged more than once per journey since there is no - * state associated with the user's ongoing journey - this will be updated in a later CL. */ private void logUserJourneyInfo(UserInfo origin, UserInfo target, @UserJourney int journey) { final long newSessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE); - synchronized (mUserJourneyToSessionIdMap) { - SparseLongArray userSessions = mUserJourneyToSessionIdMap.get(target.id); - if (userSessions == null) { - userSessions = new SparseLongArray(); - mUserJourneyToSessionIdMap.put(target.id, userSessions); - } - final long oldSessionId = userSessions.get(journey); - if (oldSessionId != INVALID_SESSION_ID) { - // potentially an incomplete or timed-out session + synchronized (mUserIdToUserJourneyMap) { + UserJourneySession userJourneySession = mUserIdToUserJourneyMap.get(target.id); + if (userJourneySession != null) { + // TODO(b/157007231): Move this logic to a separate class/file. + if ((userJourneySession.mJourney == USER_JOURNEY_USER_SWITCH_UI + && journey == USER_JOURNEY_USER_START) + || (userJourneySession.mJourney == USER_JOURNEY_USER_SWITCH_FG + && journey == USER_JOURNEY_USER_START)) { + /* + * There is already a user switch journey, and a user start journey for the same + * target user received. User start journey is most likely a part of user switch + * journey so no need to create a new journey for user start. + */ + if (DEBUG_MU) { + Slog.d(TAG, journey + " not logged as it is expected to be part of " + + userJourneySession.mJourney); + } + return; + } + /* + * Possible reasons for this condition to be true: + * - A user switch journey is received while another user switch journey is in + * process for the same user. + * - A user switch journey is received while user start journey is in process for + * the same user. + * - A user start journey is received while another user start journey is in process + * for the same user. + * In all cases potentially an incomplete, timed-out session or multiple + * simultaneous requests. It is not possible to keep track of multiple sessions for + * the same user, so previous session is abandoned. + */ FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, - oldSessionId, target.id, USER_LIFECYCLE_EVENT_UNKNOWN, - FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE); + userJourneySession.mSessionId, target.id, USER_LIFECYCLE_EVENT_UNKNOWN, + USER_LIFECYCLE_EVENT_STATE_NONE); + } + + if (DEBUG_MU) { + Slog.d(TAG, + "Starting a new journey: " + journey + " with session id: " + newSessionId); } - // update session id - userSessions.put(journey, newSessionId); + + userJourneySession = new UserJourneySession(newSessionId, journey); + mUserIdToUserJourneyMap.put(target.id, userJourneySession); + /* + * User lifecyle journey would be complete when {@code #clearSessionId} is called after + * the last expected lifecycle event for the journey. It may be possible that the last + * event is not called, e.g., user not unlocked after user switching. In such cases user + * journey is cleared after {@link USER_JOURNEY_TIMEOUT}. + */ + mHandler.removeMessages(CLEAR_USER_JOURNEY_SESSION_MSG); + mHandler.sendMessageDelayed(mHandler.obtainMessage(CLEAR_USER_JOURNEY_SESSION_MSG, + target.id), USER_JOURNEY_TIMEOUT_MS); } FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, newSessionId, @@ -2511,41 +2587,65 @@ class UserController implements Handler.Callback { } /** - * statsd helper method for logging the begin or finish of the given event for the - * UserLifecycleEventOccurred statsd atom. - * Note: This does not clear the user's journey session id - if this event represents the end of - * a particular journey, call {@link #clearSessionId} to indicate that the session is over. + * statsd helper method for logging the given event for the UserLifecycleEventOccurred statsd + * atom. */ - private void logUserLifecycleEvent(@UserIdInt int userId, @UserJourney int journey, - @UserLifecycleEvent int event, boolean begin) { + private void logUserLifecycleEvent(@UserIdInt int userId, @UserLifecycleEvent int event, + @UserLifecycleEventState int eventState) { final long sessionId; - synchronized (mUserJourneyToSessionIdMap) { - final SparseLongArray eventToSessionMap = mUserJourneyToSessionIdMap.get(userId); - if (eventToSessionMap == null || eventToSessionMap.size() == 0) { - return; - } - sessionId = eventToSessionMap.get(journey); - if (sessionId == INVALID_SESSION_ID) { + synchronized (mUserIdToUserJourneyMap) { + final UserJourneySession userJourneySession = mUserIdToUserJourneyMap.get(userId); + if (userJourneySession == null || userJourneySession.mSessionId == INVALID_SESSION_ID) { + Slog.w(TAG, "UserLifecycleEvent " + event + + " received without an active userJourneySession."); return; } + sessionId = userJourneySession.mSessionId; } FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId, - event, begin ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN - : FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH); + event, eventState); } /** - * Clears the user's session id associated with the given UserJourney (for statsd). + * Clears the {@link UserJourneySession} for a given {@link UserIdInt} and {@link UserJourney}. */ private void clearSessionId(@UserIdInt int userId, @UserJourney int journey) { - synchronized (mUserJourneyToSessionIdMap) { - if (mUserJourneyToSessionIdMap.get(userId) != null) { - mUserJourneyToSessionIdMap.get(userId).delete(journey); + synchronized (mUserIdToUserJourneyMap) { + final UserJourneySession userJourneySession = mUserIdToUserJourneyMap.get(userId); + if (userJourneySession != null && userJourneySession.mJourney == journey) { + clearSessionId(userId); } } } + /** + * Clears the {@link UserJourneySession} for a given {@link UserIdInt}. + */ + private void clearSessionId(@UserIdInt int userId) { + synchronized (mUserIdToUserJourneyMap) { + mHandler.removeMessages(CLEAR_USER_JOURNEY_SESSION_MSG); + mUserIdToUserJourneyMap.delete(userId); + } + } + + /** + * Helper class to store user journey and session id. + * + * <p> User journey tracks a chain of user lifecycle events occurring during different user + * activities such as user start, user switch, and user creation. + */ + // TODO(b/157007231): Move this class and user journey tracking logic to a separate file. + private static class UserJourneySession { + final long mSessionId; + @UserJourney final int mJourney; + + UserJourneySession(long sessionId, @UserJourney int journey) { + mJourney = journey; + mSessionId = sessionId; + } + } + private static class UserProgressListener extends IProgressListener.Stub { private volatile long mUnlockStarted; @Override diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index ae38e81fb8a3..e70de5727334 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -521,6 +521,7 @@ public class AppOpsService extends IAppOpsService.Stub { public boolean hasForegroundWatchers; public long lastTimeShowDebugToast; + public long lastTimePendingTopUid; public UidState(int uid) { this.uid = uid; @@ -542,6 +543,10 @@ public class AppOpsService extends IAppOpsService.Stub { if (mode == MODE_FOREGROUND) { if (appWidgetVisible) { return MODE_ALLOWED; + } else if (mActivityManagerInternal != null + && mActivityManagerInternal.isPendingTopUid(uid)) { + maybeLogPendingTopUid(op, mode); + return MODE_ALLOWED; } else if (state <= UID_STATE_TOP) { // process is in TOP. return MODE_ALLOWED; @@ -604,7 +609,11 @@ public class AppOpsService extends IAppOpsService.Stub { } else if (mode == MODE_ALLOWED) { switch (op) { case OP_CAMERA: - if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) { + if (mActivityManagerInternal != null + && mActivityManagerInternal.isPendingTopUid(uid)) { + maybeLogPendingTopUid(op, mode); + return MODE_ALLOWED; + } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) { return MODE_ALLOWED; } else if ((capability & DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q) != 0) { @@ -618,7 +627,11 @@ public class AppOpsService extends IAppOpsService.Stub { return MODE_IGNORED; } case OP_RECORD_AUDIO: - if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) { + if (mActivityManagerInternal != null + && mActivityManagerInternal.isPendingTopUid(uid)) { + maybeLogPendingTopUid(op, mode); + return MODE_ALLOWED; + } else if ((capability & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) { return MODE_ALLOWED; } else if ((capability & DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q) != 0) { @@ -704,6 +717,19 @@ public class AppOpsService extends IAppOpsService.Stub { mActivityManagerInternal, uid, op, mode)); } } + + + void maybeLogPendingTopUid(int op, int mode) { + final long now = System.currentTimeMillis(); + if (lastTimePendingTopUid == 0 || now - lastTimePendingTopUid > 300000) { + lastTimePendingTopUid = now; + Slog.wtf(TAG, "PendingStartActivityUids evalMode, isPendingTopUid true, uid:" + + uid + + " packageName:" + Settings.getPackageNameForUid(mContext, uid) + + " op:" + op + + " mode:" + mode); + } + } } final static class Ops extends SparseArray<Op> { diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 093e906da65e..f3c787462d61 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.NETID_UNSET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNREACHABLE; @@ -317,8 +318,7 @@ public class Vpn { * * @param defaultNetwork underlying network for VPNs following platform's default */ - public synchronized NetworkCapabilities updateCapabilities( - @Nullable Network defaultNetwork) { + public synchronized NetworkCapabilities updateCapabilities(@Nullable Network defaultNetwork) { if (mConfig == null) { // VPN is not running. return null; @@ -350,11 +350,10 @@ public class Vpn { int[] transportTypes = new int[] { NetworkCapabilities.TRANSPORT_VPN }; int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; - // VPN's meteredness is OR'd with isAlwaysMetered and meteredness of its underlying - // networks. - boolean metered = isAlwaysMetered; - boolean roaming = false; - boolean congested = false; + boolean metered = isAlwaysMetered; // metered if any underlying is metered, or alwaysMetered + boolean roaming = false; // roaming if any underlying is roaming + boolean congested = false; // congested if any underlying is congested + boolean suspended = true; // suspended if all underlying are suspended boolean hadUnderlyingNetworks = false; if (null != underlyingNetworks) { @@ -367,15 +366,24 @@ public class Vpn { transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType); } - // When we have multiple networks, we have to assume the - // worst-case link speed and restrictions. + // Merge capabilities of this underlying network. For bandwidth, assume the + // worst case. downKbps = NetworkCapabilities.minBandwidth(downKbps, underlyingCaps.getLinkDownstreamBandwidthKbps()); upKbps = NetworkCapabilities.minBandwidth(upKbps, underlyingCaps.getLinkUpstreamBandwidthKbps()); + // If this underlying network is metered, the VPN is metered (it may cost money + // to send packets on this network). metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); + // If this underlying network is roaming, the VPN is roaming (the billing structure + // is different than the usual, local one). roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); + // If this underlying network is congested, the VPN is congested (the current + // condition of the network affects the performance of this network). congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); + // If this network is not suspended, the VPN is not suspended (the VPN + // is able to transfer some data). + suspended &= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED); } } if (!hadUnderlyingNetworks) { @@ -383,6 +391,7 @@ public class Vpn { metered = true; roaming = false; congested = false; + suspended = false; } caps.setTransportTypes(transportTypes); @@ -391,6 +400,7 @@ public class Vpn { caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered); caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); + caps.setCapability(NET_CAPABILITY_NOT_SUSPENDED, !suspended); } /** diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index e16582f8e916..f360a4ae7ad8 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -342,13 +342,10 @@ public class MediaSessionService extends SystemService implements Monitor { updateUser(); } - // Called when the user with the userId is removed. @Override - public void onStopUser(int userId) { - if (DEBUG) Log.d(TAG, "onStopUser: " + userId); + public void onCleanupUser(int userId) { + if (DEBUG) Log.d(TAG, "onCleanupUser: " + userId); synchronized (mLock) { - // TODO: Also handle removing user in updateUser() because adding/switching user is - // handled in updateUser(). FullUserRecord user = getFullUserRecordLocked(userId); if (user != null) { if (user.mFullUserId == userId) { diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java index f9d805e57305..830388d8f2ac 100644 --- a/services/core/java/com/android/server/pm/AppsFilter.java +++ b/services/core/java/com/android/server/pm/AppsFilter.java @@ -720,7 +720,7 @@ public class AppsFilter { return false; } if (callingSetting == null) { - Slog.w(TAG, "No setting found for non system uid " + callingUid); + Slog.wtf(TAG, "No setting found for non system uid " + callingUid); return true; } final PackageSetting callingPkgSetting; @@ -760,7 +760,7 @@ public class AppsFilter { final AndroidPackage targetPkg = targetPkgSetting.pkg; if (targetPkg == null) { if (DEBUG_LOGGING) { - Slog.w(TAG, "shouldFilterApplication: " + "targetPkg is null"); + Slog.wtf(TAG, "shouldFilterApplication: " + "targetPkg is null"); } return true; } diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java index e82ee22c8064..37f14e8623c7 100644 --- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java @@ -31,6 +31,7 @@ import android.app.AppOpsManager; import android.app.AppOpsManager.Mode; import android.app.IApplicationThread; import android.app.admin.DevicePolicyEventLogger; +import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.ComponentName; import android.content.Context; @@ -256,6 +257,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (enabledProfileIds.length < 2) { return false; } + if (isProfileOwner(packageName, enabledProfileIds)) { + return false; + } return hasRequestedAppOpPermission( AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName); } @@ -575,6 +579,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (profileIds.length < 2) { return false; } + if (isProfileOwner(packageName, profileIds)) { + return false; + } return hasRequestedAppOpPermission( AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName) && !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds); @@ -698,6 +705,25 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { packageName); } + private boolean isProfileOwner(String packageName, int[] userIds) { + for (int userId : userIds) { + if (isProfileOwner(packageName, userId)) { + return true; + } + } + return false; + } + + private boolean isProfileOwner(String packageName, final @UserIdInt int userId) { + final ComponentName profileOwner = + mInjector.withCleanCallingIdentity(() -> + mInjector.getDevicePolicyManagerInternal().getProfileOwnerAsUser(userId)); + if (profileOwner == null) { + return false; + } + return profileOwner.getPackageName().equals(packageName); + } + private static class InjectorImpl implements Injector { private Context mContext; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f3619f22d231..395e835b6a2a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8604,7 +8604,7 @@ public class PackageManagerService extends IPackageManager.Stub // Shared lib filtering done in generateApplicationInfoFromSettingsLPw // and already converts to externally visible package name ai = generateApplicationInfoFromSettingsLPw(ps.name, - callingUid, effectiveFlags, userId); + effectiveFlags, callingUid, userId); } if (ai != null) { list.add(ai); @@ -24510,9 +24510,10 @@ public class PackageManagerService extends IPackageManager.Stub if (updatedPackageNames != null) { outUpdatedPackageNames.addAll(updatedPackageNames); } - - return true; } + + PackageManager.invalidatePackageInfoCache(); + return true; } @Override diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index e6570f38af43..3732b479c3a3 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -169,7 +169,7 @@ public class ShortcutService extends IShortcutService.Stub { static final int DEFAULT_MAX_UPDATES_PER_INTERVAL = 10; @VisibleForTesting - static final int DEFAULT_MAX_SHORTCUTS_PER_APP = 10; + static final int DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY = 15; @VisibleForTesting static final int DEFAULT_MAX_ICON_DIMENSION_DP = 96; @@ -730,7 +730,7 @@ public class ShortcutService extends IShortcutService.Stub { ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL, DEFAULT_MAX_UPDATES_PER_INTERVAL)); mMaxShortcuts = Math.max(0, (int) parser.getLong( - ConfigConstants.KEY_MAX_SHORTCUTS, DEFAULT_MAX_SHORTCUTS_PER_APP)); + ConfigConstants.KEY_MAX_SHORTCUTS, DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY)); final int iconDimensionDp = Math.max(1, injectIsLowRamDevice() ? (int) parser.getLong( diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING index d3cd1a90b0b6..2614076e9b6c 100644 --- a/services/core/java/com/android/server/pm/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/TEST_MAPPING @@ -118,6 +118,9 @@ }, { "include-filter": "com.android.server.pm.UserSystemPackageInstallerTest" + }, + { + "include-filter": "com.android.server.pm.parsing.SystemPartitionParseTest" } ] } diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java index 76c6a7aec00b..5e2c4eb45086 100644 --- a/services/core/java/com/android/server/policy/PermissionPolicyService.java +++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java @@ -16,19 +16,14 @@ package com.android.server.policy; -import static android.Manifest.permission.READ_PHONE_STATE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.AppOpsManager.OP_NONE; import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; -import static android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT; -import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; -import static android.content.pm.PackageManager.MATCH_ALL; import android.annotation.NonNull; import android.annotation.Nullable; @@ -366,46 +361,12 @@ public final class PermissionPolicyService extends SystemService { // Force synchronization as permissions might have changed synchronizePermissionsAndAppOpsForUser(userId); - restoreReadPhoneStatePermissions(userId); - // Tell observers we are initialized for this user. if (callback != null) { callback.onInitialized(userId); } } - /** - * Ensure READ_PHONE_STATE user sensitive flags are assigned properly - * TODO ntmyren: Remove once propagated, and state is repaired - */ - private void restoreReadPhoneStatePermissions(int userId) { - PackageManager pm = getContext().getPackageManager(); - List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser( - MATCH_ALL | GET_PERMISSIONS, userId); - for (int i = packageInfos.size() - 1; i >= 0; i--) { - PackageInfo pI = packageInfos.get(i); - if (pI.requestedPermissions == null) { - continue; - } - - UserHandle user = UserHandle.getUserHandleForUid(pI.applicationInfo.uid); - for (int j = pI.requestedPermissions.length - 1; j >= 0; j--) { - if (pI.requestedPermissions[j].equals(READ_PHONE_STATE)) { - int flags = pm.getPermissionFlags(READ_PHONE_STATE, pI.packageName, user); - // If the app is auto revoked for read phone state, and is only user sensitive - // when granted, clear auto revoked flag. - if ((flags & FLAG_PERMISSION_AUTO_REVOKED) != 0 - && (flags & FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0 - && (flags & FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) == 0) { - pm.updatePermissionFlags(READ_PHONE_STATE, pI.packageName, - FLAG_PERMISSION_AUTO_REVOKED, 0, user); - } - break; - } - } - } - } - @Override public void onStopUser(@UserIdInt int userId) { if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + userId + ")"); 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 9871623becf5..29c1243c299d 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -17,7 +17,7 @@ package com.android.server.stats.pull; import static android.app.AppOpsManager.OP_FLAG_SELF; -import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY; +import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS; @@ -32,6 +32,7 @@ import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION; import static android.util.MathUtils.abs; import static android.util.MathUtils.constrain; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_IS_UID; import static com.android.internal.util.FrameworkStatsLog.ANNOTATION_ID_TRUNCATE_TIMESTAMP; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; @@ -215,7 +216,7 @@ public class StatsPullAtomService extends SystemService { private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000; private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8; - private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXY; + private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED; private static final String COMMON_PERMISSION_PREFIX = "android.permission."; private static final String APP_OPS_TARGET_COLLECTION_SIZE = "app_ops_target_collection_size"; private static final String DANGEROUS_PERMISSION_STATE_SAMPLE_RATE = @@ -775,7 +776,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -955,7 +956,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -968,7 +969,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -981,7 +982,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -994,7 +995,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1064,7 +1065,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, /* PullAtomMetadata */ null, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1095,7 +1096,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1126,7 +1127,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1156,7 +1157,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1189,7 +1190,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1217,7 +1218,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1243,7 +1244,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1295,7 +1296,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1333,7 +1334,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, /* metadata */ null, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1365,7 +1366,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1384,7 +1385,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1406,7 +1407,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1450,7 +1451,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1505,7 +1506,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1567,7 +1568,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1590,7 +1591,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, /* PullAtomMetadata */ null, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1610,7 +1611,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1637,7 +1638,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1675,7 +1676,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1715,7 +1716,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1759,7 +1760,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1794,7 +1795,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1837,7 +1838,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1903,7 +1904,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1944,7 +1945,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1988,7 +1989,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2092,7 +2093,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2102,7 +2103,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2160,7 +2161,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2170,7 +2171,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2246,7 +2247,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2280,7 +2281,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, /* PullAtomMetadata */ null, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2307,7 +2308,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2343,7 +2344,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2437,7 +2438,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2457,7 +2458,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2488,7 +2489,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2524,7 +2525,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2575,7 +2576,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2613,7 +2614,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2640,7 +2641,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2699,7 +2700,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2792,7 +2793,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2819,7 +2820,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2869,7 +2870,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2925,7 +2926,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2979,7 +2980,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -2989,7 +2990,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3022,7 +3023,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3227,7 +3228,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3271,7 +3272,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3281,7 +3282,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3291,7 +3292,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3301,7 +3302,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3311,7 +3312,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3321,7 +3322,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3371,7 +3372,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -3408,7 +3409,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index a45a15ba2012..8260cb31acda 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -107,6 +107,12 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { } @Override + boolean needsZBoost() { + // Z Boost should only happen at or below the ActivityStack level. + return false; + } + + @Override boolean fillsParent() { return true; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0efb9698f4b0..d93e9764146f 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -493,10 +493,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * The launching activity which is using fixed rotation transformation. * * @see #handleTopActivityLaunchingInDifferentOrientation - * @see #setFixedRotationLaunchingApp + * @see #setFixedRotationLaunchingApp(ActivityRecord, int) * @see DisplayRotation#shouldRotateSeamlessly */ - ActivityRecord mFixedRotationLaunchingApp; + private ActivityRecord mFixedRotationLaunchingApp; final FixedRotationTransitionListener mFixedRotationTransitionListener = new FixedRotationTransitionListener(); @@ -1475,6 +1475,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return true; } + @Nullable ActivityRecord getFixedRotationLaunchingApp() { + return mFixedRotationLaunchingApp; + } + + void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r) { + setFixedRotationLaunchingAppUnchecked(r, ROTATION_UNDEFINED); + } + + void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) { + if (mFixedRotationLaunchingApp == null && r != null) { + mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation); + } else if (mFixedRotationLaunchingApp != null && r == null) { + mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this); + } + mFixedRotationLaunchingApp = r; + } + /** * Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed * rotation transform to it and indicate that the display may be rotated after it is launched. @@ -1496,7 +1513,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (!r.hasFixedRotationTransform()) { startFixedRotationTransform(r, rotation); } - mFixedRotationLaunchingApp = r; + setFixedRotationLaunchingAppUnchecked(r, rotation); if (prevRotatedLaunchingApp != null) { prevRotatedLaunchingApp.finishFixedRotationTransform(); } @@ -1524,7 +1541,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } /** - * Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is + * Clears the {@link #mFixedRotationLaunchingApp} without applying rotation to display. It is * used when the display won't rotate (e.g. the orientation from sensor has updated again before * applying rotation to display) but the launching app has been transformed. So the record need * to be cleared and restored to stop using seamless rotation and rotated configuration. @@ -1534,7 +1551,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return; } mFixedRotationLaunchingApp.finishFixedRotationTransform(); - mFixedRotationLaunchingApp = null; + setFixedRotationLaunchingAppUnchecked(null); } private void startFixedRotationTransform(WindowToken token, int rotation) { @@ -5260,7 +5277,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo rotatedLaunchingApp.finishFixedRotationTransform( () -> applyRotation(oldRotation, newRotation)); - mFixedRotationLaunchingApp = null; + setFixedRotationLaunchingAppUnchecked(null); } /** Checks whether the given activity is in size compatibility mode and notifies the change. */ @@ -5574,7 +5591,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) { // Because it won't affect display orientation, just finish the transform. animatingRecents.finishFixedRotationTransform(); - mFixedRotationLaunchingApp = null; + setFixedRotationLaunchingAppUnchecked(null); } else { // If there is already a launching activity that is not the recents, before its // transition is completed, the recents animation may be started. So if the recents diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index ebfe70c0c371..702df2a0fc63 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -577,7 +577,7 @@ public class DisplayRotation { boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) { // Display doesn't need to be frozen because application has been started in correct // rotation already, so the rest of the windows can use seamless rotation. - if (mDisplayContent.mFixedRotationLaunchingApp != null) { + if (mDisplayContent.getFixedRotationLaunchingApp() != null) { return true; } diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java index af13e3a76cf1..b627b33c036e 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java +++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java @@ -95,4 +95,27 @@ class DisplayWindowListenerController { } mDisplayListeners.finishBroadcast(); } + + void dispatchFixedRotationStarted(DisplayContent display, int newRotation) { + int count = mDisplayListeners.beginBroadcast(); + for (int i = 0; i < count; ++i) { + try { + mDisplayListeners.getBroadcastItem(i).onFixedRotationStarted( + display.mDisplayId, newRotation); + } catch (RemoteException e) { + } + } + mDisplayListeners.finishBroadcast(); + } + + void dispatchFixedRotationFinished(DisplayContent display) { + int count = mDisplayListeners.beginBroadcast(); + for (int i = 0; i < count; ++i) { + try { + mDisplayListeners.getBroadcastItem(i).onFixedRotationFinished(display.mDisplayId); + } catch (RemoteException e) { + } + } + mDisplayListeners.finishBroadcast(); + } } diff --git a/services/core/java/com/android/server/wm/TEST_MAPPING b/services/core/java/com/android/server/wm/TEST_MAPPING deleted file mode 100644 index b2e8bbe3b885..000000000000 --- a/services/core/java/com/android/server/wm/TEST_MAPPING +++ /dev/null @@ -1,23 +0,0 @@ -{ - "postsubmit": [ - { - "name": "CtsWindowManagerDeviceTestCases" - }, - { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.wm." - } - ] - }, - { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.wm." - } - ] - } - ] -} diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 6661c30723d2..9130483325b2 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -1275,14 +1275,10 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> { return true; } - final int displayWindowingMode = getWindowingMode(); if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) { return supportsSplitScreen - && WindowConfiguration.supportSplitScreenWindowingMode(activityType) - // Freeform windows and split-screen windows don't mix well, so prevent - // split windowing modes on freeform displays. - && displayWindowingMode != WINDOWING_MODE_FREEFORM; + && WindowConfiguration.supportSplitScreenWindowingMode(activityType); } if (!supportsFreeform && windowingMode == WINDOWING_MODE_FREEFORM) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5c21b2b514ce..159c59b86b43 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7922,18 +7922,23 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void syncInputTransactions() { - waitForAnimationsToComplete(); + long token = Binder.clearCallingIdentity(); + try { + waitForAnimationsToComplete(); - // Collect all input transactions from all displays to make sure we could sync all input - // windows at same time. - final SurfaceControl.Transaction t = mTransactionFactory.get(); - synchronized (mGlobalLock) { - mWindowPlacerLocked.performSurfacePlacementIfScheduled(); - mRoot.forAllDisplays(displayContent -> - displayContent.getInputMonitor().updateInputWindowsImmediately(t)); - } + // Collect all input transactions from all displays to make sure we could sync all input + // windows at same time. + final SurfaceControl.Transaction t = mTransactionFactory.get(); + synchronized (mGlobalLock) { + mWindowPlacerLocked.performSurfacePlacementIfScheduled(); + mRoot.forAllDisplays(displayContent -> + displayContent.getInputMonitor().updateInputWindowsImmediately(t)); + } - t.syncInputWindows().apply(); + t.syncInputWindows().apply(); + } finally { + Binder.restoreCallingIdentity(token); + } } /** diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java index 20b109bc06f7..2ec6df5878ef 100644 --- a/services/core/java/com/android/server/wm/WindowProcessController.java +++ b/services/core/java/com/android/server/wm/WindowProcessController.java @@ -44,6 +44,7 @@ import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_N import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.app.ActivityThread; import android.app.IApplicationThread; import android.app.ProfilerInfo; @@ -1065,6 +1066,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio // to track as a separate apk in the process. packageName = info.packageName; } + // update ActivityManagerService.PendingStartActivityUids list. + if (topProcessState == ActivityManager.PROCESS_STATE_TOP) { + mAtm.mAmInternal.updatePendingTopUid(mUid, true); + } // Posting the message at the front of queue so WM lock isn't held when we call into AM, // and the process state of starting activity can be updated quicker which will give it a // higher scheduling group. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index fd18e6f9c39a..e9aff88d0f80 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2262,7 +2262,29 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mHasSurface = hasSurface; } + /** + * Checks whether one of the Windows in a Display embedded in this Window can be an IME target. + */ + private boolean canWindowInEmbeddedDisplayBeImeTarget() { + final int embeddedDisplayContentsSize = mEmbeddedDisplayContents.size(); + for (int i = embeddedDisplayContentsSize - 1; i >= 0; i--) { + final DisplayContent edc = mEmbeddedDisplayContents.valueAt(i); + if (edc.forAllWindows(WindowState::canBeImeTarget, true)) { + return true; + } + } + return false; + } + boolean canBeImeTarget() { + // If any of the embedded windows can be the IME target, this window will be the final IME + // target. This is because embedded windows are on a different display in WM so it would + // cause confusion trying to set the IME to a window on a different display. Instead, just + // make the host window the IME target. + if (canWindowInEmbeddedDisplayBeImeTarget()) { + return true; + } + if (mIsImWindow) { // IME windows can't be IME targets. IME targets are required to be below the IME // windows and that wouldn't be possible if the IME window is its own target...silly. diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 18c25c142113..b7a9ba56c013 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7973,6 +7973,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final int userHandle = UserHandle.getCallingUserId(); boolean requireAutoTimeChanged = false; synchronized (getLockObject()) { + if (isManagedProfile(userHandle)) { + throw new SecurityException("Managed profile cannot set auto time required"); + } ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (admin.requireAutoTime != required) { @@ -12727,6 +12730,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { Binder.restoreCallingIdentity(ident); } } + + @Override + public ComponentName getProfileOwnerAsUser(int userHandle) { + return DevicePolicyManagerService.this.getProfileOwnerAsUser(userHandle); + } } private Intent createShowAdminSupportIntent(ComponentName admin, int userId) { diff --git a/services/people/java/com/android/server/people/data/AppUsageStatsData.java b/services/people/java/com/android/server/people/data/AppUsageStatsData.java new file mode 100644 index 000000000000..6baef38fffc1 --- /dev/null +++ b/services/people/java/com/android/server/people/data/AppUsageStatsData.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.people.data; + +import com.android.internal.annotations.VisibleForTesting; + +/** The data containing package usage info. */ +public class AppUsageStatsData { + + private int mLaunchCount; + + private int mChosenCount; + + @VisibleForTesting + public AppUsageStatsData(int chosenCount, int launchCount) { + this.mChosenCount = chosenCount; + this.mLaunchCount = launchCount; + } + + public AppUsageStatsData() { + } + + public int getLaunchCount() { + return mLaunchCount; + } + + void incrementLaunchCountBy(int launchCount) { + this.mLaunchCount += launchCount; + } + + public int getChosenCount() { + return mChosenCount; + } + + void incrementChosenCountBy(int chosenCount) { + this.mChosenCount += chosenCount; + } +} diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java index 107c41a47507..bbb0215788fb 100644 --- a/services/people/java/com/android/server/people/data/DataManager.java +++ b/services/people/java/com/android/server/people/data/DataManager.java @@ -257,13 +257,16 @@ public class DataManager { } /** - * Queries launch counts of apps within {@code packageNameFilter} between {@code startTime} - * and {@code endTime}. + * Queries usage stats of apps within {@code packageNameFilter} between {@code startTime} and + * {@code endTime}. + * + * @return a map which keys are package names and values are {@link AppUsageStatsData}. */ @NonNull - public Map<String, Integer> queryAppLaunchCount(@UserIdInt int callingUserId, long startTime, + public Map<String, AppUsageStatsData> queryAppUsageStats( + @UserIdInt int callingUserId, long startTime, long endTime, Set<String> packageNameFilter) { - return UsageStatsQueryHelper.queryAppLaunchCount(callingUserId, startTime, endTime, + return UsageStatsQueryHelper.queryAppUsageStats(callingUserId, startTime, endTime, packageNameFilter); } diff --git a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java index 6e6fea93c803..d89bbe9dd14e 100644 --- a/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java +++ b/services/people/java/com/android/server/people/data/UsageStatsQueryHelper.java @@ -137,27 +137,48 @@ class UsageStatsQueryHelper { } /** - * Queries {@link UsageStatsManagerInternal} for launch count of apps within {@code - * packageNameFilter} between {@code startTime} and {@code endTime}.obfuscateInstantApps + * Queries {@link UsageStatsManagerInternal} for usage stats of apps within {@code + * packageNameFilter} between {@code startTime} and {@code endTime}. * - * @return a map which keys are package names and values are app launch counts. + * @return a map which keys are package names and values are {@link AppUsageStatsData}. */ - static Map<String, Integer> queryAppLaunchCount(@UserIdInt int userId, long startTime, + static Map<String, AppUsageStatsData> queryAppUsageStats(@UserIdInt int userId, long startTime, long endTime, Set<String> packageNameFilter) { List<UsageStats> stats = getUsageStatsManagerInternal().queryUsageStatsForUser(userId, UsageStatsManager.INTERVAL_BEST, startTime, endTime, /* obfuscateInstantApps= */ false); - Map<String, Integer> aggregatedStats = new ArrayMap<>(); + Map<String, AppUsageStatsData> aggregatedStats = new ArrayMap<>(); for (UsageStats stat : stats) { String packageName = stat.getPackageName(); if (packageNameFilter.contains(packageName)) { - aggregatedStats.put(packageName, - aggregatedStats.getOrDefault(packageName, 0) + stat.getAppLaunchCount()); + AppUsageStatsData packageStats = aggregatedStats.computeIfAbsent(packageName, + (key) -> new AppUsageStatsData()); + packageStats.incrementChosenCountBy(sumChooserCounts(stat.mChooserCounts)); + packageStats.incrementLaunchCountBy(stat.getAppLaunchCount()); } } return aggregatedStats; } + private static int sumChooserCounts(ArrayMap<String, ArrayMap<String, Integer>> chooserCounts) { + int sum = 0; + if (chooserCounts == null) { + return sum; + } + int chooserCountsSize = chooserCounts.size(); + for (int i = 0; i < chooserCountsSize; i++) { + ArrayMap<String, Integer> counts = chooserCounts.valueAt(i); + if (counts == null) { + continue; + } + final int annotationSize = counts.size(); + for (int j = 0; j < annotationSize; j++) { + sum += counts.valueAt(j); + } + } + return sum; + } + private void onInAppConversationEnded(@NonNull PackageData packageData, @NonNull UsageEvents.Event endEvent) { ComponentName activityName = diff --git a/services/people/java/com/android/server/people/prediction/SharesheetModelScorer.java b/services/people/java/com/android/server/people/prediction/SharesheetModelScorer.java index 76f252efb412..c77843cfb044 100644 --- a/services/people/java/com/android/server/people/prediction/SharesheetModelScorer.java +++ b/services/people/java/com/android/server/people/prediction/SharesheetModelScorer.java @@ -27,17 +27,18 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ChooserActivity; +import com.android.server.people.data.AppUsageStatsData; import com.android.server.people.data.DataManager; import com.android.server.people.data.Event; import java.time.Duration; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.PriorityQueue; import java.util.concurrent.TimeUnit; +import java.util.function.Function; /** Ranking scorer for Sharesheet targets. */ class SharesheetModelScorer { @@ -50,8 +51,8 @@ class SharesheetModelScorer { private static final float RECENCY_SCORE_SUBSEQUENT_DECAY = 0.02F; private static final long ONE_MONTH_WINDOW = TimeUnit.DAYS.toMillis(30); private static final long FOREGROUND_APP_PROMO_TIME_WINDOW = TimeUnit.MINUTES.toMillis(10); + private static final float USAGE_STATS_CHOOSER_SCORE_INITIAL_DECAY = 0.9F; private static final float FREQUENTLY_USED_APP_SCORE_INITIAL_DECAY = 0.3F; - private static final float FREQUENTLY_USED_APP_SCORE_DECAY = 0.9F; @VisibleForTesting static final float FOREGROUND_APP_WEIGHT = 0F; @VisibleForTesting @@ -192,14 +193,16 @@ class SharesheetModelScorer { targetsList.add(index, shareTarget); } promoteForegroundApp(shareTargetMap, dataManager, callingUserId); - promoteFrequentlyUsedApps(shareTargetMap, targetsLimit, dataManager, callingUserId); + promoteMostChosenAndFrequentlyUsedApps(shareTargetMap, targetsLimit, dataManager, + callingUserId); } /** - * Promotes frequently used sharing apps, if recommended apps based on sharing history have not - * reached the limit (e.g. user did not share any content in last couple weeks) + * Promotes frequently chosen sharing apps and frequently used sharing apps as per + * UsageStatsManager, if recommended apps based on sharing history have not reached the limit + * (e.g. user did not share any content in last couple weeks) */ - private static void promoteFrequentlyUsedApps( + private static void promoteMostChosenAndFrequentlyUsedApps( Map<String, List<ShareTargetPredictor.ShareTarget>> shareTargetMap, int targetsLimit, @NonNull DataManager dataManager, @UserIdInt int callingUserId) { int validPredictionNum = 0; @@ -217,39 +220,50 @@ class SharesheetModelScorer { return; } long now = System.currentTimeMillis(); - Map<String, Integer> appLaunchCountsMap = dataManager.queryAppLaunchCount( - callingUserId, now - ONE_MONTH_WINDOW, now, shareTargetMap.keySet()); - List<Pair<String, Integer>> appLaunchCounts = new ArrayList<>(); - minValidScore *= FREQUENTLY_USED_APP_SCORE_INITIAL_DECAY; - for (Map.Entry<String, Integer> entry : appLaunchCountsMap.entrySet()) { - if (entry.getValue() > 0) { - appLaunchCounts.add(new Pair(entry.getKey(), entry.getValue())); - } + Map<String, AppUsageStatsData> appStatsMap = + dataManager.queryAppUsageStats( + callingUserId, now - ONE_MONTH_WINDOW, now, shareTargetMap.keySet()); + // Promotes frequently chosen sharing apps as per UsageStatsManager. + minValidScore = promoteApp(shareTargetMap, appStatsMap, AppUsageStatsData::getChosenCount, + USAGE_STATS_CHOOSER_SCORE_INITIAL_DECAY * minValidScore, minValidScore); + // Promotes frequently used sharing apps as per UsageStatsManager. + promoteApp(shareTargetMap, appStatsMap, AppUsageStatsData::getLaunchCount, + FREQUENTLY_USED_APP_SCORE_INITIAL_DECAY * minValidScore, minValidScore); + } + + private static float promoteApp( + Map<String, List<ShareTargetPredictor.ShareTarget>> shareTargetMap, + Map<String, AppUsageStatsData> appStatsMap, + Function<AppUsageStatsData, Integer> countFunc, float baseScore, float minValidScore) { + int maxCount = 0; + for (AppUsageStatsData data : appStatsMap.values()) { + maxCount = Math.max(maxCount, countFunc.apply(data)); } - Collections.sort(appLaunchCounts, (p1, p2) -> -Integer.compare(p1.second, p2.second)); - for (Pair<String, Integer> entry : appLaunchCounts) { - if (!shareTargetMap.containsKey(entry.first)) { - continue; - } - ShareTargetPredictor.ShareTarget target = shareTargetMap.get(entry.first).get(0); - if (target.getScore() > 0f) { - continue; - } - target.setScore(minValidScore); - minValidScore *= FREQUENTLY_USED_APP_SCORE_DECAY; - if (DEBUG) { - Slog.d(TAG, String.format( - "SharesheetModel: promoteFrequentUsedApps packageName: %s, className: %s," - + " total:%.2f", - target.getAppTarget().getPackageName(), - target.getAppTarget().getClassName(), - target.getScore())); - } - validPredictionNum++; - if (validPredictionNum == targetsLimit) { - return; + if (maxCount > 0) { + for (Map.Entry<String, AppUsageStatsData> entry : appStatsMap.entrySet()) { + if (!shareTargetMap.containsKey(entry.getKey())) { + continue; + } + ShareTargetPredictor.ShareTarget target = shareTargetMap.get(entry.getKey()).get(0); + if (target.getScore() > 0f) { + continue; + } + float curScore = baseScore * countFunc.apply(entry.getValue()) / maxCount; + target.setScore(curScore); + if (curScore > 0) { + minValidScore = Math.min(minValidScore, curScore); + } + if (DEBUG) { + Slog.d(TAG, String.format( + "SharesheetModel: promote as per AppUsageStats packageName: %s, " + + "className: %s, total:%.2f", + target.getAppTarget().getPackageName(), + target.getAppTarget().getClassName(), + target.getScore())); + } } } + return minValidScore; } /** diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java index d78dad55e181..715404194a28 100644 --- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java +++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java @@ -37,7 +37,9 @@ import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.AppOpsManager.Mode; +import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManagerInternal; +import android.content.ComponentName; import android.content.ContextWrapper; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -97,6 +99,7 @@ public class CrossProfileAppsServiceImplRoboTest { private static final int WORK_PROFILE_USER_ID = 10; private static final int WORK_PROFILE_UID = 3333; private static final int OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID = 20; + private static final int OUTSIDE_PROFILE_GROUP_USER_ID = 30; private final ContextWrapper mContext = ApplicationProvider.getApplicationContext(); private final UserManager mUserManager = mContext.getSystemService(UserManager.class); @@ -226,6 +229,7 @@ public class CrossProfileAppsServiceImplRoboTest { PERSONAL_PROFILE_USER_ID, WORK_PROFILE_USER_ID, OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID); + shadowUserManager.addProfileIds(OUTSIDE_PROFILE_GROUP_USER_ID); } @Before @@ -504,6 +508,36 @@ public class CrossProfileAppsServiceImplRoboTest { } @Test + public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerWorkProfile_returnsFalse() { + when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(WORK_PROFILE_USER_ID)) + .thenReturn(buildCrossProfileComponentName()); + assertThat(mCrossProfileAppsServiceImpl + .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME)) + .isFalse(); + } + + @Test + public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerOtherProfile_returnsFalse() { + // Normally, the DPC would not be a profile owner of the personal profile, but for the + // purposes of this test, it is just a profile owner of any profile within the profile + // group. + when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(PERSONAL_PROFILE_USER_ID)) + .thenReturn(buildCrossProfileComponentName()); + assertThat(mCrossProfileAppsServiceImpl + .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME)) + .isFalse(); + } + + @Test + public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerOutsideProfileGroup_returnsTrue() { + when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(OUTSIDE_PROFILE_GROUP_USER_ID)) + .thenReturn(buildCrossProfileComponentName()); + assertThat(mCrossProfileAppsServiceImpl + .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME)) + .isTrue(); + } + + @Test public void canUserAttemptToConfigureInteractAcrossProfiles_returnsTrue() { assertThat(mCrossProfileAppsServiceImpl .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME)) @@ -607,6 +641,10 @@ public class CrossProfileAppsServiceImplRoboTest { .hideAsParsed()).hideAsFinal()); } + private ComponentName buildCrossProfileComponentName() { + return new ComponentName(CROSS_PROFILE_APP_PACKAGE_NAME, "testClassName"); + } + private class TestInjector implements CrossProfileAppsServiceImpl.Injector { @Override diff --git a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java index 03d9ad51e6c5..30ff1196cec0 100644 --- a/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/people/data/UsageStatsQueryHelperTest.java @@ -34,6 +34,7 @@ import android.app.usage.UsageStats; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import android.content.LocusId; +import android.util.ArrayMap; import androidx.test.InstrumentationRegistry; @@ -196,39 +197,42 @@ public final class UsageStatsQueryHelperTest { } @Test - public void testQueryAppLaunchCount() { - - UsageStats packageStats1 = createUsageStats(PKG_NAME_1, 2); - UsageStats packageStats2 = createUsageStats(PKG_NAME_1, 3); - UsageStats packageStats3 = createUsageStats(PKG_NAME_2, 1); + public void testQueryAppUsageStats() { + UsageStats packageStats1 = createUsageStats(PKG_NAME_1, 2, createDummyChooserCounts()); + UsageStats packageStats2 = createUsageStats(PKG_NAME_1, 3, null); + UsageStats packageStats3 = createUsageStats(PKG_NAME_2, 1, createDummyChooserCounts()); when(mUsageStatsManagerInternal.queryUsageStatsForUser(anyInt(), anyInt(), anyLong(), anyLong(), anyBoolean())).thenReturn( List.of(packageStats1, packageStats2, packageStats3)); - Map<String, Integer> appLaunchCounts = mHelper.queryAppLaunchCount(USER_ID_PRIMARY, 90_000L, - 200_000L, Set.of(PKG_NAME_1, PKG_NAME_2)); + Map<String, AppUsageStatsData> appLaunchChooserCountCounts = + mHelper.queryAppUsageStats(USER_ID_PRIMARY, 90_000L, + 200_000L, Set.of(PKG_NAME_1, PKG_NAME_2)); - assertEquals(2, appLaunchCounts.size()); - assertEquals(5, (long) appLaunchCounts.get(PKG_NAME_1)); - assertEquals(1, (long) appLaunchCounts.get(PKG_NAME_2)); + assertEquals(2, appLaunchChooserCountCounts.size()); + assertEquals(4, (long) appLaunchChooserCountCounts.get(PKG_NAME_1).getChosenCount()); + assertEquals(5, (long) appLaunchChooserCountCounts.get(PKG_NAME_1).getLaunchCount()); + assertEquals(4, (long) appLaunchChooserCountCounts.get(PKG_NAME_2).getChosenCount()); + assertEquals(1, (long) appLaunchChooserCountCounts.get(PKG_NAME_2).getLaunchCount()); } @Test - public void testQueryAppLaunchCount_packageNameFiltered() { - - UsageStats packageStats1 = createUsageStats(PKG_NAME_1, 2); - UsageStats packageStats2 = createUsageStats(PKG_NAME_1, 3); - UsageStats packageStats3 = createUsageStats(PKG_NAME_2, 1); + public void testQueryAppUsageStats_packageNameFiltered() { + UsageStats packageStats1 = createUsageStats(PKG_NAME_1, 2, createDummyChooserCounts()); + UsageStats packageStats2 = createUsageStats(PKG_NAME_1, 3, createDummyChooserCounts()); + UsageStats packageStats3 = createUsageStats(PKG_NAME_2, 1, null); when(mUsageStatsManagerInternal.queryUsageStatsForUser(anyInt(), anyInt(), anyLong(), anyLong(), anyBoolean())).thenReturn( List.of(packageStats1, packageStats2, packageStats3)); - Map<String, Integer> appLaunchCounts = mHelper.queryAppLaunchCount(USER_ID_PRIMARY, 90_000L, - 200_000L, - Set.of(PKG_NAME_1)); + Map<String, AppUsageStatsData> appLaunchChooserCountCounts = + mHelper.queryAppUsageStats(USER_ID_PRIMARY, 90_000L, + 200_000L, + Set.of(PKG_NAME_1)); - assertEquals(1, appLaunchCounts.size()); - assertEquals(5, (long) appLaunchCounts.get(PKG_NAME_1)); + assertEquals(1, appLaunchChooserCountCounts.size()); + assertEquals(8, (long) appLaunchChooserCountCounts.get(PKG_NAME_1).getChosenCount()); + assertEquals(5, (long) appLaunchChooserCountCounts.get(PKG_NAME_1).getLaunchCount()); } private void addUsageEvents(UsageEvents.Event... events) { @@ -237,13 +241,27 @@ public final class UsageStatsQueryHelperTest { anyInt())).thenReturn(usageEvents); } - private static UsageStats createUsageStats(String packageName, int launchCount) { + private static UsageStats createUsageStats(String packageName, int launchCount, + ArrayMap<String, ArrayMap<String, Integer>> chooserCounts) { UsageStats packageStats = new UsageStats(); packageStats.mPackageName = packageName; packageStats.mAppLaunchCount = launchCount; + packageStats.mChooserCounts = chooserCounts; return packageStats; } + private static ArrayMap<String, ArrayMap<String, Integer>> createDummyChooserCounts() { + ArrayMap<String, ArrayMap<String, Integer>> chooserCounts = new ArrayMap<>(); + ArrayMap<String, Integer> counts1 = new ArrayMap<>(); + counts1.put("text", 2); + counts1.put("image", 1); + chooserCounts.put("intent1", counts1); + ArrayMap<String, Integer> counts2 = new ArrayMap<>(); + counts2.put("video", 1); + chooserCounts.put("intent2", counts2); + return chooserCounts; + } + private static <T> void addLocalServiceMock(Class<T> clazz, T mock) { LocalServices.removeServiceForTest(clazz); LocalServices.addService(clazz, mock); diff --git a/services/tests/servicestests/src/com/android/server/people/prediction/SharesheetModelScorerTest.java b/services/tests/servicestests/src/com/android/server/people/prediction/SharesheetModelScorerTest.java index 9fc17763b8e0..45fff48ade55 100644 --- a/services/tests/servicestests/src/com/android/server/people/prediction/SharesheetModelScorerTest.java +++ b/services/tests/servicestests/src/com/android/server/people/prediction/SharesheetModelScorerTest.java @@ -31,6 +31,7 @@ import android.app.usage.UsageEvents; import android.os.UserHandle; import android.util.Range; +import com.android.server.people.data.AppUsageStatsData; import com.android.server.people.data.DataManager; import com.android.server.people.data.Event; import com.android.server.people.data.EventHistory; @@ -257,6 +258,39 @@ public final class SharesheetModelScorerTest { } @Test + public void testComputeScoreForAppShare_promoteFrequentlyChosenApps() { + when(mEventHistory1.getEventIndex(anySet())).thenReturn(mEventIndex1); + when(mEventHistory2.getEventIndex(anySet())).thenReturn(mEventIndex2); + when(mEventHistory3.getEventIndex(anySet())).thenReturn(mEventIndex3); + when(mEventHistory4.getEventIndex(anySet())).thenReturn(mEventIndex4); + when(mEventHistory5.getEventIndex(anySet())).thenReturn(mEventIndex5); + when(mEventHistory1.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex6); + when(mEventHistory2.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex7); + when(mEventHistory3.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex8); + when(mEventHistory4.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex9); + when(mEventHistory5.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex10); + when(mDataManager.queryAppUsageStats(anyInt(), anyLong(), anyLong(), anySet())) + .thenReturn( + Map.of(PACKAGE_1, new AppUsageStatsData(1, 0), + PACKAGE_2, new AppUsageStatsData(2, 0), + PACKAGE_3, new AppUsageStatsData(3, 0))); + + SharesheetModelScorer.computeScoreForAppShare( + List.of(mShareTarget1, mShareTarget2, mShareTarget3, mShareTarget4, mShareTarget5, + mShareTarget6), + Event.TYPE_SHARE_TEXT, 20, NOW, mDataManager, USER_ID); + + verify(mDataManager, times(1)).queryAppUsageStats(anyInt(), anyLong(), anyLong(), + anySet()); + assertEquals(0.9f, mShareTarget5.getScore(), DELTA); + assertEquals(0.6f, mShareTarget3.getScore(), DELTA); + assertEquals(0.3f, mShareTarget1.getScore(), DELTA); + assertEquals(0f, mShareTarget2.getScore(), DELTA); + assertEquals(0f, mShareTarget4.getScore(), DELTA); + assertEquals(0f, mShareTarget6.getScore(), DELTA); + } + + @Test public void testComputeScoreForAppShare_promoteFrequentlyUsedApps() { when(mEventHistory1.getEventIndex(anySet())).thenReturn(mEventIndex1); when(mEventHistory2.getEventIndex(anySet())).thenReturn(mEventIndex2); @@ -268,22 +302,22 @@ public final class SharesheetModelScorerTest { when(mEventHistory3.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex8); when(mEventHistory4.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex9); when(mEventHistory5.getEventIndex(Event.TYPE_SHARE_TEXT)).thenReturn(mEventIndex10); - when(mDataManager.queryAppLaunchCount(anyInt(), anyLong(), anyLong(), anySet())) + when(mDataManager.queryAppUsageStats(anyInt(), anyLong(), anyLong(), anySet())) .thenReturn( - Map.of(PACKAGE_1, 1, - PACKAGE_2, 2, - PACKAGE_3, 3)); + Map.of(PACKAGE_1, new AppUsageStatsData(0, 1), + PACKAGE_2, new AppUsageStatsData(0, 2), + PACKAGE_3, new AppUsageStatsData(1, 0))); SharesheetModelScorer.computeScoreForAppShare( List.of(mShareTarget1, mShareTarget2, mShareTarget3, mShareTarget4, mShareTarget5, mShareTarget6), Event.TYPE_SHARE_TEXT, 20, NOW, mDataManager, USER_ID); - verify(mDataManager, times(1)).queryAppLaunchCount(anyInt(), anyLong(), anyLong(), + verify(mDataManager, times(1)).queryAppUsageStats(anyInt(), anyLong(), anyLong(), anySet()); - assertEquals(0.3f, mShareTarget5.getScore(), DELTA); + assertEquals(0.9f, mShareTarget5.getScore(), DELTA); assertEquals(0.27f, mShareTarget3.getScore(), DELTA); - assertEquals(0.243f, mShareTarget1.getScore(), DELTA); + assertEquals(0.135f, mShareTarget1.getScore(), DELTA); assertEquals(0f, mShareTarget2.getScore(), DELTA); assertEquals(0f, mShareTarget4.getScore(), DELTA); assertEquals(0f, mShareTarget6.getScore(), DELTA); @@ -306,18 +340,19 @@ public final class SharesheetModelScorerTest { when(mEventIndex3.getMostRecentActiveTimeSlot()).thenReturn(FIVE_DAYS_AGO); when(mEventIndex4.getMostRecentActiveTimeSlot()).thenReturn(EIGHT_DAYS_AGO); when(mEventIndex5.getMostRecentActiveTimeSlot()).thenReturn(null); - when(mDataManager.queryAppLaunchCount(anyInt(), anyLong(), anyLong(), anySet())) + when(mDataManager.queryAppUsageStats(anyInt(), anyLong(), anyLong(), anySet())) .thenReturn( - Map.of(PACKAGE_1, 1, - PACKAGE_2, 2, - PACKAGE_3, 3)); + Map.of(PACKAGE_1, new AppUsageStatsData(0, 1), + PACKAGE_2, new AppUsageStatsData(0, 2), + PACKAGE_3, new AppUsageStatsData(1, 0))); SharesheetModelScorer.computeScoreForAppShare( List.of(mShareTarget1, mShareTarget2, mShareTarget3, mShareTarget4, mShareTarget5, mShareTarget6), Event.TYPE_SHARE_TEXT, 4, NOW, mDataManager, USER_ID); - verify(mDataManager, never()).queryAppLaunchCount(anyInt(), anyLong(), anyLong(), anySet()); + verify(mDataManager, never()).queryAppUsageStats(anyInt(), anyLong(), anyLong(), + anySet()); assertEquals(0.4f, mShareTarget1.getScore(), DELTA); assertEquals(0.35f, mShareTarget2.getScore(), DELTA); assertEquals(0.33f, mShareTarget3.getScore(), DELTA); diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 6a882985d305..e4acdfe93fd4 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -720,6 +720,8 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected static final long INTERVAL = 10000; + // This doesn't need to match the max shortcuts limit in the framework, and tests should either + // use this or set their own limit for testing, without assuming any particular max value. protected static final int MAX_SHORTCUTS = 10; protected static final int MAX_UPDATES_PER_INTERVAL = 3; diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java index 320dacff4888..db02524e6fab 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java @@ -234,7 +234,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals(ShortcutService.DEFAULT_RESET_INTERVAL_SEC * 1000, mService.getResetIntervalForTest()); - assertEquals(ShortcutService.DEFAULT_MAX_SHORTCUTS_PER_APP, + assertEquals(ShortcutService.DEFAULT_MAX_SHORTCUTS_PER_ACTIVITY, mService.getMaxShortcutsForTest()); assertEquals(ShortcutService.DEFAULT_MAX_UPDATES_PER_INTERVAL, @@ -393,6 +393,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } public void testPushDynamicShortcut() { + // Change the max number of shortcuts. + mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5"); setCaller(CALLING_PACKAGE_1, USER_0); @@ -400,12 +402,11 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { final ShortcutInfo s2 = makeShortcut("s2"); final ShortcutInfo s3 = makeShortcut("s3"); final ShortcutInfo s4 = makeShortcut("s4"); - - final ShortcutInfo s10 = makeShortcut("s10"); - final ShortcutInfo s11 = makeShortcut("s11"); - final ShortcutInfo s12 = makeShortcut("s12"); - final ShortcutInfo s13 = makeShortcut("s13"); - final ShortcutInfo s14 = makeShortcut("s14"); + final ShortcutInfo s5 = makeShortcut("s5"); + final ShortcutInfo s6 = makeShortcut("s6"); + final ShortcutInfo s7 = makeShortcut("s7"); + final ShortcutInfo s8 = makeShortcut("s8"); + final ShortcutInfo s9 = makeShortcut("s9"); // Test push as first shortcut mManager.pushDynamicShortcut(s1); @@ -440,63 +441,61 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { mInjectedCurrentTimeMillis += INTERVAL; // reset // Test push as last - assertTrue(mManager.addDynamicShortcuts(makeShortcuts("s5", "s6", "s7", "s8", "s9"))); - mManager.pushDynamicShortcut(s10); + mManager.pushDynamicShortcut(s5); assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10"); - assertEquals(0, getCallerShortcut("s10").getRank()); - assertEquals(1, getCallerShortcut("s5").getRank()); - assertEquals(6, getCallerShortcut("s3").getRank()); - assertEquals(7, getCallerShortcut("s1").getRank()); - assertEquals(8, getCallerShortcut("s2").getRank()); - assertEquals(9, getCallerShortcut("s4").getRank()); + "s1", "s2", "s3", "s4", "s5"); + assertEquals(0, getCallerShortcut("s5").getRank()); + assertEquals(1, getCallerShortcut("s3").getRank()); + assertEquals(2, getCallerShortcut("s1").getRank()); + assertEquals(3, getCallerShortcut("s2").getRank()); + assertEquals(4, getCallerShortcut("s4").getRank()); // Push when max has already reached - mManager.pushDynamicShortcut(s11); + mManager.pushDynamicShortcut(s6); assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s5", "s6", "s7", "s8", "s9", "s10", "s11"); - assertEquals(0, getCallerShortcut("s11").getRank()); - assertEquals(1, getCallerShortcut("s10").getRank()); - assertEquals(9, getCallerShortcut("s2").getRank()); + "s1", "s2", "s3", "s5", "s6"); + assertEquals(0, getCallerShortcut("s6").getRank()); + assertEquals(1, getCallerShortcut("s5").getRank()); + assertEquals(4, getCallerShortcut("s2").getRank()); mInjectedCurrentTimeMillis += INTERVAL; // reset // Push with different activity - s12.setActivity(makeComponent(ShortcutActivity2.class)); - mManager.pushDynamicShortcut(s12); + s7.setActivity(makeComponent(ShortcutActivity2.class)); + mManager.pushDynamicShortcut(s7); assertEquals(makeComponent(ShortcutActivity2.class), - getCallerShortcut("s12").getActivity()); - assertEquals(0, getCallerShortcut("s12").getRank()); + getCallerShortcut("s7").getActivity()); + assertEquals(0, getCallerShortcut("s7").getRank()); // Push to update shortcut with different activity final ShortcutInfo s1_2 = makeShortcut("s1"); s1_2.setActivity(makeComponent(ShortcutActivity2.class)); s1_2.setRank(1); mManager.pushDynamicShortcut(s1_2); - assertEquals(0, getCallerShortcut("s12").getRank()); + assertEquals(0, getCallerShortcut("s7").getRank()); assertEquals(1, getCallerShortcut("s1").getRank()); - assertEquals(0, getCallerShortcut("s11").getRank()); - assertEquals(1, getCallerShortcut("s10").getRank()); - assertEquals(7, getCallerShortcut("s3").getRank()); - assertEquals(8, getCallerShortcut("s2").getRank()); + assertEquals(0, getCallerShortcut("s6").getRank()); + assertEquals(1, getCallerShortcut("s5").getRank()); + assertEquals(2, getCallerShortcut("s3").getRank()); + assertEquals(3, getCallerShortcut("s2").getRank()); mInjectedCurrentTimeMillis += INTERVAL; // reset // Test push when dropped shortcut is cached - s13.setLongLived(); - s13.setRank(100); - mManager.pushDynamicShortcut(s13); - assertEquals(9, getCallerShortcut("s13").getRank()); + s8.setLongLived(); + s8.setRank(100); + mManager.pushDynamicShortcut(s8); + assertEquals(4, getCallerShortcut("s8").getRank()); runWithCaller(LAUNCHER_1, USER_0, () -> { - mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s13"), HANDLE_USER_0); + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s8"), HANDLE_USER_0); }); - mManager.pushDynamicShortcut(s14); + mManager.pushDynamicShortcut(s9); assertShortcutIds(assertAllNotKeyFieldsOnly(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s14"); + "s1", "s2", "s3", "s5", "s6", "s7", "s9"); // Verify s13 stayed as cached assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), - "s13"); + "s8"); } public void testUnlimitedCalls() { diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java index 50d290a837cd..621966535306 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest11.java @@ -30,6 +30,8 @@ import android.content.pm.LauncherApps.ShortcutQuery; import android.content.pm.ShortcutInfo; import android.os.test.TestLooper; +import com.android.server.pm.ShortcutService.ConfigConstants; + import org.mockito.ArgumentCaptor; import java.util.List; @@ -372,9 +374,11 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { } public void testShortcutChangeCallback_pushDynamicShortcut_existingId() { + // Change the max number of shortcuts. + mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3"); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", - "s6", "s7", "s8", "s9", "s10")))); + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3")))); }); ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); @@ -384,7 +388,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - mManager.pushDynamicShortcut(makeShortcut("s5")); + mManager.pushDynamicShortcut(makeShortcut("s2")); }); mTestLooper.dispatchAll(); @@ -396,13 +400,15 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { assertWith(shortcuts.getValue()) .areAllWithKeyFieldsOnly() - .haveIds("s5"); + .haveIds("s2"); } public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletion() { + // Change the max number of shortcuts. + mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3"); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", - "s6", "s7", "s8", "s9", "s10")))); + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3")))); }); ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); @@ -412,7 +418,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - mManager.pushDynamicShortcut(makeShortcut("s11")); + mManager.pushDynamicShortcut(makeShortcut("s4")); }); mTestLooper.dispatchAll(); @@ -427,31 +433,33 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { assertWith(changedShortcuts.getValue()) .areAllWithKeyFieldsOnly() - .haveIds("s11"); + .haveIds("s4"); assertWith(removedShortcuts.getValue()) .areAllWithKeyFieldsOnly() - .haveIds("s10"); + .haveIds("s3"); } public void testShortcutChangeCallback_pushDynamicShortcut_causeDeletionButCached() { + // Change the max number of shortcuts. + mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3"); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2", "s3", "s4", "s5", - "s6", "s7", "s8", "s9")))); - ShortcutInfo s10 = makeLongLivedShortcut("s10"); - s10.setRank(10); - mManager.pushDynamicShortcut(s10); // Add a long lived shortcut to the end of the list. + assertTrue(mManager.setDynamicShortcuts((makeShortcuts("s1", "s2")))); + ShortcutInfo s3 = makeLongLivedShortcut("s3"); + s3.setRank(3); + mManager.pushDynamicShortcut(s3); // Add a long lived shortcut to the end of the list. }); ShortcutChangeCallback callback = mock(ShortcutChangeCallback.class); runWithCaller(LAUNCHER_1, USER_0, () -> { - mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s10"), HANDLE_USER_0); + mLauncherApps.cacheShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0); mLauncherApps.registerShortcutChangeCallback(callback, QUERY_MATCH_ALL, mTestLooper.getNewExecutor()); }); runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { - mManager.pushDynamicShortcut(makeShortcut("s11")); + mManager.pushDynamicShortcut(makeShortcut("s4")); }); mTestLooper.dispatchAll(); @@ -463,7 +471,7 @@ public class ShortcutManagerTest11 extends BaseShortcutManagerTest { assertWith(shortcuts.getValue()) .areAllWithKeyFieldsOnly() - .haveIds("s10", "s11"); + .haveIds("s3", "s4"); } public void testShortcutChangeCallback_disableShortcuts() { diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt index 086c845fa4b6..0f028f05d514 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingTestBase.kt @@ -23,7 +23,6 @@ import android.content.pm.ConfigurationInfo import android.content.pm.FeatureInfo import android.content.pm.InstrumentationInfo import android.content.pm.PackageInfo -import android.content.pm.PackageManager import android.content.pm.PackageParser import android.content.pm.PackageUserState import android.content.pm.PermissionInfo @@ -38,7 +37,6 @@ import com.android.server.pm.parsing.pkg.AndroidPackage import com.android.server.pm.pkg.PackageStateUnserialized import com.android.server.testutils.mockThrowOnUnmocked import com.android.server.testutils.whenever -import org.junit.After import org.junit.BeforeClass import org.mockito.Mockito import org.mockito.Mockito.anyInt @@ -49,7 +47,7 @@ open class AndroidPackageParsingTestBase { companion object { - private const val VERIFY_ALL_APKS = true + private const val VERIFY_ALL_APKS = false /** For auditing memory usage differences */ private const val DUMP_HPROF_TO_EXTERNAL = false @@ -93,21 +91,25 @@ open class AndroidPackageParsingTestBase { lateinit var newPackages: List<AndroidPackage> - private val thrownInSetUp = mutableListOf<Throwable>() - @Suppress("ConstantConditionIf") @JvmStatic @BeforeClass fun setUpPackages() { this.oldPackages = apks.mapNotNull { - tryOrNull { + try { packageParser.parsePackage(it, PackageParser.PARSE_IS_SYSTEM_DIR, false) + } catch (ignored: Exception) { + // Parsing issues will be caught by SystemPartitionParseTest + null } } this.newPackages = apks.mapNotNull { - tryOrNull { + try { packageParser2.parsePackage(it, PackageParser.PARSE_IS_SYSTEM_DIR, false) + } catch (ignored: Exception) { + // Parsing issues will be caught by SystemPartitionParseTest + null } } @@ -144,41 +146,6 @@ open class AndroidPackageParsingTestBase { this.pkg = aPkg whenever(pkgState) { PackageStateUnserialized() } } - - private fun <T> tryOrNull(block: () -> T) = try { - block() - } catch (e: PackageParser.PackageParserException) { - if (e.error != PackageManager.INSTALL_PARSE_FAILED_SKIPPED) { - thrownInSetUp.add(e) - } - null - } catch (t: Throwable) { - thrownInSetUp.add(t) - null - } - } - - @After - fun verifySetUpPackages() { - if (thrownInSetUp.isEmpty()) return - val exception = AssertionError("setUpPackages failed with ${thrownInSetUp.size} errors:\n" + - thrownInSetUp.joinToString(separator = "\n") { it.message.orEmpty() }) - - /* - Testing infrastructure doesn't currently support errors thrown in @AfterClass, - so instead it's thrown here. But to avoid throwing a massive repeated stack for every - test method, only throw on the first method run in the class, clearing the list so that - subsequent methods can run without failing. Doing this in @After lets true method - failures propagate, as those should throw before this does. - - This will cause the failure to be attached to a different method depending on run order, - which could make comparisons difficult. So if a failure points here, it's worth - checking failures for all methods in all subclasses. - - TODO: When infrastructure supports @AfterClass errors, move this - */ - thrownInSetUp.clear() - throw exception } // The following methods dump an exact set of fields from the object to compare, because @@ -285,7 +252,8 @@ open class AndroidPackageParsingTestBase { secondaryCpuAbi=${this.secondaryCpuAbi} secondaryNativeLibraryDir=${this.secondaryNativeLibraryDir} sourceDir=${this.sourceDir} - splitDependencies=${this.splitDependencies.sequence().map { it.first to it.second?.contentToString() }.joinToString()} + splitDependencies=${this.splitDependencies.sequence() + .map { it.first to it.second?.contentToString() }.joinToString()} splitNames=${this.splitNames?.contentToString()} splitPublicSourceDirs=${this.splitPublicSourceDirs?.contentToString()} splitSourceDirs=${this.splitSourceDirs?.contentToString()} @@ -348,7 +316,9 @@ open class AndroidPackageParsingTestBase { initOrder=${this.initOrder} isSyncable=${this.isSyncable} multiprocess=${this.multiprocess} - pathPermissions=${this.pathPermissions?.joinToString { "readPermission=${it.readPermission}\nwritePermission=${it.writePermission}" }} + pathPermissions=${this.pathPermissions?.joinToString { + "readPermission=${it.readPermission}\nwritePermission=${it.writePermission}" + }} readPermission=${this.readPermission} uriPermissionPatterns=${this.uriPermissionPatterns?.contentToString()} writePermission=${this.writePermission} @@ -370,7 +340,9 @@ open class AndroidPackageParsingTestBase { compileSdkVersionCodename=${this.compileSdkVersionCodename} configPreferences=${this.configPreferences?.joinToString { it.dumpToString() }} coreApp=${this.coreApp} - featureGroups=${this.featureGroups?.joinToString { it.features?.joinToString { featureInfo -> featureInfo.dumpToString() }.orEmpty() }} + featureGroups=${this.featureGroups?.joinToString { + it.features?.joinToString { featureInfo -> featureInfo.dumpToString() }.orEmpty() + }} firstInstallTime=${this.firstInstallTime} gids=${gids?.contentToString()} installLocation=${this.installLocation} @@ -396,7 +368,8 @@ open class AndroidPackageParsingTestBase { sharedUserId=${this.sharedUserId} sharedUserLabel=${this.sharedUserLabel} signatures=${this.signatures?.joinToString { it.toCharsString() }} - signingInfo=${this.signingInfo?.signingCertificateHistory?.joinToString { it.toCharsString() }.orEmpty()} + signingInfo=${this.signingInfo?.signingCertificateHistory + ?.joinToString { it.toCharsString() }.orEmpty()} splitNames=${this.splitNames?.contentToString()} splitRevisionCodes=${this.splitRevisionCodes?.contentToString()} targetOverlayableName=${this.targetOverlayableName} diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt new file mode 100644 index 000000000000..605841df0c5a --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm.parsing + +import android.content.pm.PackageManager +import android.content.pm.PackageParser +import android.platform.test.annotations.Postsubmit +import com.android.server.pm.PackageManagerService +import org.junit.Test + +/** + * This test parses all the system APKs on the device image to ensure that they succeed. + * + * Any invalid APKs should be removed from the device or marked as skipped through any mechanism + * for ignoring packages. + * + * This test must run on deferred postsubmit. Targeted presubmit will not catch errors fast enough, + * and the low failure rate does not warrant global presubmit. + */ +@Postsubmit +class SystemPartitionParseTest { + + private val APKS = PackageManagerService.SYSTEM_PARTITIONS + .flatMap { listOfNotNull(it.appFolder, it.privAppFolder, it.overlayFolder) } + .flatMap { + it.walkTopDown() + .filter { it.name.endsWith(".apk") } + .toList() + } + .distinct() + + private val parser = PackageParser2.forParsingFileWithDefaults() + + @Test + fun verify() { + val exceptions = APKS + .map { + runCatching { + parser.parsePackage(it, PackageParser.PARSE_IS_SYSTEM_DIR, false) + } + } + .mapNotNull { it.exceptionOrNull() } + .filterNot { (it as? PackageParser.PackageParserException)?.error == + PackageManager.INSTALL_PARSE_FAILED_SKIPPED } + + if (exceptions.isEmpty()) return + + throw AssertionError("verify failed with ${exceptions.size} errors:\n" + + exceptions.joinToString(separator = "\n") { it.message.orEmpty() }) + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index d45ecc9a3329..ced780475fb7 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -6557,7 +6557,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(si.getPackage()).thenReturn(PKG_P); when(si.getId()).thenReturn("convo"); when(si.getUserId()).thenReturn(USER_SYSTEM); - when(si.getShortLabel()).thenReturn("Hello"); + when(si.getLabel()).thenReturn("Hello"); when(si.isLongLived()).thenReturn(true); when(si.isEnabled()).thenReturn(true); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(Arrays.asList(si)); @@ -6591,7 +6591,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(si.getPackage()).thenReturn(PKG_P); when(si.getId()).thenReturn("convo"); when(si.getUserId()).thenReturn(USER_SYSTEM); - when(si.getShortLabel()).thenReturn("Hello"); + when(si.getLabel()).thenReturn("Hello"); when(si.isLongLived()).thenReturn(false); when(mLauncherApps.getShortcuts(any(), any())).thenReturn(Arrays.asList(si)); 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 4da5adfeb872..063568d0380c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -1405,14 +1405,14 @@ public class ActivityRecordTests extends ActivityTestsBase { mActivity.setVisibility(true); display.rotateInDifferentOrientationIfNeeded(mActivity); - display.mFixedRotationLaunchingApp = mActivity; + display.setFixedRotationLaunchingAppUnchecked(mActivity); displayRotation.updateRotationUnchecked(true /* forceUpdate */); assertTrue(displayRotation.isRotatingSeamlessly()); // The launching rotated app should not be cleared when waiting for remote rotation. display.continueUpdateOrientationForDiffOrienLaunchingApp(); - assertNotNull(display.mFixedRotationLaunchingApp); + assertNotNull(display.getFixedRotationLaunchingApp()); // Simulate the rotation has been updated to previous one, e.g. sensor updates before the // remote rotation is completed. @@ -1438,10 +1438,10 @@ public class ActivityRecordTests extends ActivityTestsBase { displayRotation.updateRotationUnchecked(true /* forceUpdate */); doReturn(false).when(displayRotation).isWaitingForRemoteRotation(); clearInvocations(mActivity); - display.mFixedRotationLaunchingApp = mActivity; + display.setFixedRotationLaunchingAppUnchecked(mActivity); display.sendNewConfiguration(); - assertNull(display.mFixedRotationLaunchingApp); + assertNull(display.getFixedRotationLaunchingApp()); assertFalse(mActivity.hasFixedRotationTransform()); } @@ -1497,7 +1497,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // rotation should be applied when creating snapshot surface if the display rotation may be // changed according to the activity orientation. assertTrue(mActivity.hasFixedRotationTransform()); - assertEquals(mActivity, mActivity.mDisplayContent.mFixedRotationLaunchingApp); + assertEquals(mActivity, mActivity.mDisplayContent.getFixedRotationLaunchingApp()); } /** 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 4b43ceb6e07f..bd616a3a96f3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -140,6 +140,12 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase { public void onDisplayRemoved(int displayId) { removed.add(displayId); } + + @Override + public void onFixedRotationStarted(int displayId, int newRotation) {} + + @Override + public void onFixedRotationFinished(int displayId) {} }; mService.mWindowManager.registerDisplayWindowListener(listener); // Check that existing displays call added diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index 209db62f38de..f330f0fc9f0b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -343,7 +343,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { initializeRecentsAnimationController(mController, homeActivity); - assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp); + assertEquals(homeActivity, mDefaultDisplay.getFixedRotationLaunchingApp()); // Check that the home app is in portrait assertEquals(Configuration.ORIENTATION_PORTRAIT, @@ -353,7 +353,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { // top rotated record should be cleared. mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); assertFalse(homeActivity.hasFixedRotationTransform()); - assertNull(mDefaultDisplay.mFixedRotationLaunchingApp); + assertNull(mDefaultDisplay.getFixedRotationLaunchingApp()); } @Test @@ -367,7 +367,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { (mDefaultDisplay.getRotation() + 1) % 4); assertTrue(activity.hasFixedRotationTransform()); - assertEquals(activity, mDefaultDisplay.mFixedRotationLaunchingApp); + assertEquals(activity, mDefaultDisplay.getFixedRotationLaunchingApp()); // Before the transition is done, the recents animation is triggered. initializeRecentsAnimationController(mController, homeActivity); @@ -377,7 +377,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { mController.cleanupAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); // The rotation transform should be cleared after updating orientation with display. assertFalse(activity.hasFixedRotationTransform()); - assertNull(mDefaultDisplay.mFixedRotationLaunchingApp); + assertNull(mDefaultDisplay.getFixedRotationLaunchingApp()); } @Test @@ -436,7 +436,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { // The transform state should keep because we expect to listen the signal from the // transition executed by moving the task to front. assertTrue(homeActivity.hasFixedRotationTransform()); - assertEquals(homeActivity, mDefaultDisplay.mFixedRotationLaunchingApp); + assertEquals(homeActivity, mDefaultDisplay.getFixedRotationLaunchingApp()); mDefaultDisplay.mFixedRotationTransitionListener.onAppTransitionFinishedLocked( homeActivity.token); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 52a51875427f..512042cdf7b9 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -40,6 +40,9 @@ import static org.junit.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.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import android.platform.test.annotations.Presubmit; @@ -82,6 +85,25 @@ public class TaskDisplayAreaTests extends WindowTestsBase { } @Test + public void testActivityWithZBoost_taskDisplayAreaDoesNotMoveUp() { + final ActivityStack stack = createTaskStackOnDisplay( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, mDisplayContent); + final Task task = createTaskInStack(stack, 0 /* userId */); + final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(mDisplayContent); + task.addChild(activity, 0 /* addPos */); + final TaskDisplayArea taskDisplayArea = activity.getDisplayArea(); + activity.mNeedsAnimationBoundsLayer = true; + activity.mNeedsZBoost = true; + spyOn(taskDisplayArea.mSurfaceAnimator); + + mDisplayContent.assignChildLayers(mTransaction); + + assertThat(activity.needsZBoost()).isTrue(); + assertThat(taskDisplayArea.needsZBoost()).isFalse(); + verify(taskDisplayArea.mSurfaceAnimator, never()).setLayer(eq(mTransaction), anyInt()); + } + + @Test public void testStackPositionChildAt() { // Test that always-on-top stack can't be moved to position other than top. final ActivityStack stack1 = createTaskStackOnDisplay(mDisplayContent); 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 0346329eccd4..8ce5daa635f2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -270,6 +270,26 @@ public class WindowStateTests extends WindowTestsBase { } @Test + public void testCanWindowWithEmbeddedDisplayBeImeTarget() { + final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow"); + final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow"); + + imeWindow.setHasSurface(true); + appWindow.setHasSurface(true); + + appWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE; + assertFalse(appWindow.canBeImeTarget()); + + DisplayContent secondDisplay = createNewDisplay(); + final WindowState embeddedWindow = createWindow(null, TYPE_APPLICATION, secondDisplay, + "embeddedWindow"); + appWindow.addEmbeddedDisplayContent(secondDisplay); + embeddedWindow.setHasSurface(true); + embeddedWindow.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE; + assertTrue(appWindow.canBeImeTarget()); + } + + @Test public void testGetWindow() { final WindowState root = createWindow(null, TYPE_APPLICATION, "root"); final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild"); diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java index a35fb407bca9..0ffafd45613a 100644 --- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java +++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java @@ -92,6 +92,9 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork { break; case TRANSPORT_VPN: mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN); + // VPNs deduce the SUSPENDED capability from their underlying networks and there + // is no public API to let VPN services set it. + mNetworkCapabilities.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); mScore = ConnectivityConstants.VPN_DEFAULT_SCORE; break; default: diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index d2b26d3bfd58..83ca9b28e9b5 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -5387,8 +5387,6 @@ public class ConnectivityServiceTest { // Even though the VPN is unvalidated, it becomes the default network for our app. callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent); - // TODO: this looks like a spurious callback. - callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, vpnNetworkAgent); callback.assertNoCallback(); assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore()); @@ -5418,6 +5416,47 @@ public class ConnectivityServiceTest { } @Test + public void testVpnStartsWithUnderlyingCaps() throws Exception { + final int uid = Process.myUid(); + + final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback(); + final NetworkRequest vpnNetworkRequest = new NetworkRequest.Builder() + .removeCapability(NET_CAPABILITY_NOT_VPN) + .addTransportType(TRANSPORT_VPN) + .build(); + mCm.registerNetworkCallback(vpnNetworkRequest, vpnNetworkCallback); + vpnNetworkCallback.assertNoCallback(); + + // Connect cell. It will become the default network, and in the absence of setting + // underlying networks explicitly it will become the sole underlying network for the vpn. + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); + mCellNetworkAgent.connect(true); + + final TestNetworkAgentWrapper vpnNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN); + final ArraySet<UidRange> ranges = new ArraySet<>(); + ranges.add(new UidRange(uid, uid)); + mMockVpn.setNetworkAgent(vpnNetworkAgent); + mMockVpn.connect(); + mMockVpn.setUids(ranges); + vpnNetworkAgent.connect(true /* validated */, false /* hasInternet */, + false /* isStrictMode */); + + vpnNetworkCallback.expectAvailableCallbacks(vpnNetworkAgent.getNetwork(), + false /* suspended */, false /* validated */, false /* blocked */, TIMEOUT_MS); + vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent.getNetwork(), TIMEOUT_MS, + nc -> nc.hasCapability(NET_CAPABILITY_VALIDATED)); + + final NetworkCapabilities nc = mCm.getNetworkCapabilities(vpnNetworkAgent.getNetwork()); + assertTrue(nc.hasTransport(TRANSPORT_VPN)); + assertTrue(nc.hasTransport(TRANSPORT_CELLULAR)); + assertFalse(nc.hasTransport(TRANSPORT_WIFI)); + assertTrue(nc.hasCapability(NET_CAPABILITY_VALIDATED)); + assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); + assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + } + + @Test public void testVpnSetUnderlyingNetworks() throws Exception { final int uid = Process.myUid(); @@ -5447,9 +5486,12 @@ public class ConnectivityServiceTest { assertFalse(nc.hasTransport(TRANSPORT_WIFI)); // For safety reasons a VPN without underlying networks is considered metered. assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED)); + // A VPN without underlying networks is not suspended. + assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); // Connect cell and use it as an underlying network. mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); + mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); mCellNetworkAgent.connect(true); mService.setUnderlyingNetworksForVpn( @@ -5458,10 +5500,12 @@ public class ConnectivityServiceTest { vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, (caps) -> caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); + mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); mWiFiNetworkAgent.connect(true); mService.setUnderlyingNetworksForVpn( @@ -5470,7 +5514,8 @@ public class ConnectivityServiceTest { vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, (caps) -> caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); // Don't disconnect, but note the VPN is not using wifi any more. mService.setUnderlyingNetworksForVpn( @@ -5479,16 +5524,36 @@ public class ConnectivityServiceTest { vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, (caps) -> caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + + // Remove NOT_SUSPENDED from the only network and observe VPN is now suspended. + mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); + vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, + (caps) -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, vpnNetworkAgent); - // Use Wifi but not cell. Note the VPN is now unmetered. + // Add NOT_SUSPENDED again and observe VPN is no longer suspended. + mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED); + vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, + (caps) -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, vpnNetworkAgent); + + // Use Wifi but not cell. Note the VPN is now unmetered and not suspended. mService.setUnderlyingNetworksForVpn( new Network[] { mWiFiNetworkAgent.getNetwork() }); vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, (caps) -> caps.hasTransport(TRANSPORT_VPN) && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && caps.hasCapability(NET_CAPABILITY_NOT_METERED)); + && caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); // Use both again. mService.setUnderlyingNetworksForVpn( @@ -5497,7 +5562,37 @@ public class ConnectivityServiceTest { vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, (caps) -> caps.hasTransport(TRANSPORT_VPN) && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) - && !caps.hasCapability(NET_CAPABILITY_NOT_METERED)); + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + + // Cell is suspended again. As WiFi is not, this should not cause a callback. + mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_SUSPENDED); + vpnNetworkCallback.assertNoCallback(); + + // Stop using WiFi. The VPN is suspended again. + mService.setUnderlyingNetworksForVpn( + new Network[] { mCellNetworkAgent.getNetwork() }); + vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, + (caps) -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_CELLULAR) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + // While the SUSPENDED callback should in theory be sent here, it is not. This is + // a bug in ConnectivityService, but as the SUSPENDED and RESUMED callbacks have never + // been public and are deprecated and slated for removal, there is no sense in spending + // resources fixing this bug now. + + // Use both again. + mService.setUnderlyingNetworksForVpn( + new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() }); + + vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, + (caps) -> caps.hasTransport(TRANSPORT_VPN) + && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI) + && !caps.hasCapability(NET_CAPABILITY_NOT_METERED) + && caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); + // As above, the RESUMED callback not being sent here is a bug, but not a bug that's + // worth anybody's time to fix. // Disconnect cell. Receive update without even removing the dead network from the // underlying networks – it's dead anyway. Not metered any more. diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 1994d1f2ed45..f8d8a56b57c0 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; @@ -606,6 +607,7 @@ public class VpnTest { .addCapability(NET_CAPABILITY_NOT_METERED) .addCapability(NET_CAPABILITY_NOT_ROAMING) .addCapability(NET_CAPABILITY_NOT_CONGESTED) + .addCapability(NET_CAPABILITY_NOT_SUSPENDED) .setLinkUpstreamBandwidthKbps(20)); setMockedNetworks(networks); @@ -621,6 +623,7 @@ public class VpnTest { assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); Vpn.applyUnderlyingCapabilities( mConnectivityManager, @@ -635,6 +638,7 @@ public class VpnTest { assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); + assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {wifi}, caps, false /* isAlwaysMetered */); @@ -646,6 +650,7 @@ public class VpnTest { assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); Vpn.applyUnderlyingCapabilities( mConnectivityManager, new Network[] {wifi}, caps, true /* isAlwaysMetered */); @@ -657,6 +662,7 @@ public class VpnTest { assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); Vpn.applyUnderlyingCapabilities( mConnectivityManager, @@ -671,6 +677,7 @@ public class VpnTest { assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)); } /** |