diff options
776 files changed, 9447 insertions, 5505 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index fd92979bd593..9a417e9da3dd 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -19,11 +19,17 @@ java_defaults { // Add java_aconfig_libraries to here to add them to the core framework srcs: [ ":android.os.flags-aconfig-java{.generated_srcjars}", + ":android.os.vibrator.flags-aconfig-java{.generated_srcjars}", ":android.security.flags-aconfig-java{.generated_srcjars}", ":camera_platform_flags_core_java_lib{.generated_srcjars}", ":com.android.window.flags.window-aconfig-java{.generated_srcjars}", ":com.android.text.flags-aconfig-java{.generated_srcjars}", + ":telecom_flags_core_java_lib{.generated_srcjars}", + ":android.companion.virtual.flags-aconfig-java{.generated_srcjars}", + ":android.view.inputmethod.flags-aconfig-java{.generated_srcjars}", ], + // Add aconfig-annotations-lib as a dependency for the optimization + libs: ["aconfig-annotations-lib"], } // Default flags for java_aconfig_libraries that go into framework-minus-apex @@ -41,6 +47,13 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +// Telecom +java_aconfig_library { + name: "telecom_flags_core_java_lib", + aconfig_declarations: "telecom_flags", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Window aconfig_declarations { name: "com.android.window.flags.window-aconfig", @@ -67,6 +80,11 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +cc_aconfig_library { + name: "aconfig_text_flags_c_lib", + aconfig_declarations: "com.android.text.flags-aconfig", +} + // Security aconfig_declarations { name: "android.security.flags-aconfig", @@ -80,6 +98,14 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +java_aconfig_library { + name: "android.security.flags-aconfig-java-host", + aconfig_declarations: "android.security.flags-aconfig", + host_supported: true, + test: true, + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // OS aconfig_declarations { name: "android.os.flags-aconfig", @@ -92,3 +118,42 @@ java_aconfig_library { aconfig_declarations: "android.os.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// VirtualDeviceManager +java_aconfig_library { + name: "android.companion.virtual.flags-aconfig-java", + aconfig_declarations: "android.companion.virtual.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + +aconfig_declarations { + name: "android.companion.virtual.flags-aconfig", + package: "android.companion.virtual.flags", + srcs: ["core/java/android/companion/virtual/*.aconfig"], +} + +// InputMethod +aconfig_declarations { + name: "android.view.inputmethod.flags-aconfig", + package: "android.view.inputmethod", + srcs: ["core/java/android/view/inputmethod/flags.aconfig"], +} + +java_aconfig_library { + name: "android.view.inputmethod.flags-aconfig-java", + aconfig_declarations: "android.view.inputmethod.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + +// Vibrator +aconfig_declarations { + name: "android.os.vibrator.flags-aconfig", + package: "android.os.vibrator", + srcs: ["core/java/android/os/vibrator/*.aconfig"], +} + +java_aconfig_library { + name: "android.os.vibrator.flags-aconfig-java", + aconfig_declarations: "android.os.vibrator.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} 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 9d363c806f5f..3af36ebb08ca 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -28,6 +28,7 @@ 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.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_ID; import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_SIZE; import static com.android.server.blob.BlobStoreConfig.LOGV; @@ -1915,7 +1916,7 @@ public class BlobStoreManagerService extends SystemService { mStatsManager.setPullAtomCallback( FrameworkStatsLog.BLOB_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } diff --git a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java index 17076bc4eea4..66c1efca0000 100644 --- a/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java +++ b/apex/jobscheduler/framework/java/android/os/PowerExemptionManager.java @@ -419,6 +419,14 @@ public class PowerExemptionManager { */ public static final int REASON_SYSTEM_EXEMPT_APP_OP = 327; + /** + * Granted by {@link com.android.server.pm.PackageArchiverService} to the installer responsible + * for unarchiving an app. + * + * @hide + */ + public static final int REASON_PACKAGE_UNARCHIVE = 328; + /** @hide The app requests out-out. */ public static final int REASON_OPT_OUT_REQUESTED = 1000; @@ -502,6 +510,7 @@ public class PowerExemptionManager { REASON_ACTIVE_DEVICE_ADMIN, REASON_MEDIA_NOTIFICATION_TRANSFER, REASON_PACKAGE_INSTALLER, + REASON_PACKAGE_UNARCHIVE, }) @Retention(RetentionPolicy.SOURCE) public @interface ReasonCode {} diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 1be07fdfcceb..b8596d5a3926 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -538,7 +538,7 @@ public class DeviceIdleController extends SystemService /** * Package names the system has white-listed to opt out of power save restrictions, - * except for device idle mode. + * except for device idle modes (light and full doze). */ private final ArrayMap<String, Integer> mPowerSaveWhitelistAppsExceptIdle = new ArrayMap<>(); diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java index 90a6455a4a8b..adb4d85101a3 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/MetricsHelper.java @@ -16,6 +16,7 @@ package com.android.server.alarm; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED; import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__LISTENER; @@ -31,7 +32,6 @@ import android.app.StatsManager; import android.content.Context; import android.os.SystemClock; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.FrameworkStatsLog; import java.util.function.Supplier; @@ -51,7 +51,7 @@ class MetricsHelper { void registerPuller(Supplier<AlarmStore> alarmStoreSupplier) { final StatsManager statsManager = mContext.getSystemService(StatsManager.class); statsManager.setPullAtomCallback(FrameworkStatsLog.PENDING_ALARM_INFO, null, - BackgroundThread.getExecutor(), (atomTag, data) -> { + DIRECT_EXECUTOR, (atomTag, data) -> { if (atomTag != FrameworkStatsLog.PENDING_ALARM_INFO) { throw new UnsupportedOperationException("Unknown tag" + atomTag); } diff --git a/cmds/idmap2/libidmap2/XmlParser.cpp b/cmds/idmap2/libidmap2/XmlParser.cpp index 1d784600459d..780715561006 100644 --- a/cmds/idmap2/libidmap2/XmlParser.cpp +++ b/cmds/idmap2/libidmap2/XmlParser.cpp @@ -130,11 +130,14 @@ Result<Res_value> XmlParser::Node::GetAttributeValue(ResourceId attr, } Result<Res_value> XmlParser::Node::GetAttributeValue(const std::string& name) const { + String16 name16; return FindAttribute(parser_, name, [&](size_t index) -> bool { - size_t len; - const String16 key16(parser_.getAttributeName(index, &len)); - std::string key = String8(key16).c_str(); - return key == name; + if (name16.empty()) { + name16 = String16(name.c_str(), name.size()); + } + size_t key_len; + const auto key16 = parser_.getAttributeName(index, &key_len); + return key16 && name16.size() == key_len && name16 == key16; }); } diff --git a/core/api/current.txt b/core/api/current.txt index e00362407fc7..df41b1ff6066 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39351,10 +39351,10 @@ package android.security { } public final class FileIntegrityManager { - method @FlaggedApi(Flags.FLAG_FSVERITY_API) @Nullable public byte[] getFsverityDigest(@NonNull java.io.File) throws java.io.IOException; + method @FlaggedApi(Flags.FLAG_FSVERITY_API) @Nullable public byte[] getFsVerityDigest(@NonNull java.io.File) throws java.io.IOException; method public boolean isApkVeritySupported(); method @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public boolean isAppSourceCertificateTrusted(@NonNull java.security.cert.X509Certificate) throws java.security.cert.CertificateEncodingException; - method @FlaggedApi(Flags.FLAG_FSVERITY_API) public void setupFsverity(@NonNull java.io.File) throws java.io.IOException; + method @FlaggedApi(Flags.FLAG_FSVERITY_API) public void setupFsVerity(@NonNull java.io.File) throws java.io.IOException; } public final class KeyChain { @@ -42273,7 +42273,7 @@ package android.telecom { field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10 field public static final int PROPERTY_IS_ADHOC_CONFERENCE = 8192; // 0x2000 field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40 - field public static final int PROPERTY_IS_TRANSACTIONAL = 32768; // 0x8000 + field @FlaggedApi(Flags.FLAG_VOIP_APP_ACTIONS_SUPPORT) public static final int PROPERTY_IS_TRANSACTIONAL = 32768; // 0x8000 field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800 field public static final int PROPERTY_RTT = 1024; // 0x400 field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100 diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 7f1e28961108..e4846b8affd4 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -529,6 +529,7 @@ package android.provider { public static final class Settings.Config extends android.provider.Settings.NameValueTable { method @RequiresPermission(android.Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS) public static void clearMonitorCallback(@NonNull android.content.ContentResolver); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean deleteString(@NonNull String, @NonNull String); + method @NonNull public static java.util.Map<java.lang.String,java.lang.String> getAllStrings(); method @Nullable @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static String getString(@NonNull String); method @NonNull @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static java.util.Map<java.lang.String,java.lang.String> getStrings(@NonNull String, @NonNull java.util.List<java.lang.String>); method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static int getSyncDisabledMode(); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index adbd06c10f47..0c619815ac78 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3213,6 +3213,7 @@ package android.companion.virtual { method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener); method public void removeSoundEffectListener(@NonNull android.companion.virtual.VirtualDeviceManager.SoundEffectListener); + method @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY) @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDevicePolicy(int, int); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void unregisterIntentInterceptor(@NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); } @@ -3546,6 +3547,7 @@ package android.content { field public static final String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS"; field @Deprecated public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED"; field public static final String ACTION_SPLIT_CONFIGURATION_CHANGED = "android.intent.action.SPLIT_CONFIGURATION_CHANGED"; + field public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE"; field public static final String ACTION_UPGRADE_SETUP = "android.intent.action.UPGRADE_SETUP"; field public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED"; @@ -3795,6 +3797,13 @@ package android.content.pm { public class PackageArchiver { method @RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES, android.Manifest.permission.REQUEST_DELETE_PACKAGES}) public void requestArchive(@NonNull String, @NonNull android.content.IntentSender) throws android.content.pm.PackageManager.NameNotFoundException; + method @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public void requestUnarchive(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException; + field public static final String EXTRA_UNARCHIVE_ALL_USERS = "android.content.pm.extra.UNARCHIVE_ALL_USERS"; + field public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME"; + } + + public class PackageInfo implements android.os.Parcelable { + field public boolean isArchived; } public class PackageInstaller { @@ -4016,6 +4025,7 @@ package android.content.pm { field @Deprecated public static final int INTENT_FILTER_VERIFICATION_SUCCESS = 1; // 0x1 field @Deprecated public static final int MASK_PERMISSION_FLAGS = 255; // 0xff field public static final int MATCH_ANY_USER = 4194304; // 0x400000 + field public static final long MATCH_ARCHIVED_PACKAGES = 4294967296L; // 0x100000000L field public static final int MATCH_CLONE_PROFILE = 536870912; // 0x20000000 field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000 field public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 536870912; // 0x20000000 @@ -7281,8 +7291,11 @@ package android.media.audiofx { package android.media.audiopolicy { - public class AudioMix { + public class AudioMix implements android.os.Parcelable { + method public int describeContents(); method public int getMixState(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioMix> CREATOR; field public static final int MIX_STATE_DISABLED = -1; // 0xffffffff field public static final int MIX_STATE_IDLE = 0; // 0x0 field public static final int MIX_STATE_MIXING = 1; // 0x1 @@ -7291,15 +7304,18 @@ package android.media.audiopolicy { } public static class AudioMix.Builder { - ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException; + ctor public AudioMix.Builder(@NonNull android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix.Builder setDevice(@NonNull android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException; - method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException; + method public android.media.audiopolicy.AudioMix.Builder setFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException; } - public class AudioMixingRule { + public class AudioMixingRule implements android.os.Parcelable { + method public int describeContents(); method public int getTargetMixRole(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.audiopolicy.AudioMixingRule> CREATOR; field public static final int MIX_ROLE_INJECTOR = 1; // 0x1 field public static final int MIX_ROLE_PLAYERS = 0; // 0x0 field public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 2; // 0x2 @@ -7336,6 +7352,7 @@ package android.media.audiopolicy { method public boolean setUidDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public boolean setUserIdDeviceAffinity(int, @NonNull java.util.List<android.media.AudioDeviceInfo>); method public String toLogFriendlyString(); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int updateMixingRules(@NonNull java.util.List<android.util.Pair<android.media.audiopolicy.AudioMix,android.media.audiopolicy.AudioMixingRule>>); field public static final int FOCUS_POLICY_DUCKING_DEFAULT = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; // 0x0 field public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; // 0x1 @@ -17321,7 +17338,6 @@ package android.telephony.satellite { field public static final int NT_RADIO_TECHNOLOGY_NR_NTN = 2; // 0x2 field public static final int NT_RADIO_TECHNOLOGY_PROPRIETARY = 4; // 0x4 field public static final int NT_RADIO_TECHNOLOGY_UNKNOWN = 0; // 0x0 - field public static final int SATELLITE_ACCESS_BARRED = 16; // 0x10 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE = 0; // 0x0 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7; // 0x7 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE = 6; // 0x6 @@ -17331,13 +17347,6 @@ package android.telephony.satellite { field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3; // 0x3 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2; // 0x2 field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1; // 0xffffffff - field public static final int SATELLITE_ERROR = 1; // 0x1 - field public static final int SATELLITE_ERROR_NONE = 0; // 0x0 - field public static final int SATELLITE_INVALID_ARGUMENTS = 8; // 0x8 - field public static final int SATELLITE_INVALID_MODEM_STATE = 7; // 0x7 - field public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6; // 0x6 - field public static final int SATELLITE_MODEM_BUSY = 22; // 0x16 - field public static final int SATELLITE_MODEM_ERROR = 4; // 0x4 field public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3; // 0x3 field public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2; // 0x2 field public static final int SATELLITE_MODEM_STATE_IDLE = 0; // 0x0 @@ -17345,21 +17354,29 @@ package android.telephony.satellite { field public static final int SATELLITE_MODEM_STATE_OFF = 4; // 0x4 field public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5; // 0x5 field public static final int SATELLITE_MODEM_STATE_UNKNOWN = -1; // 0xffffffff - field public static final int SATELLITE_NETWORK_ERROR = 5; // 0x5 - field public static final int SATELLITE_NETWORK_TIMEOUT = 17; // 0x11 - field public static final int SATELLITE_NOT_AUTHORIZED = 19; // 0x13 - field public static final int SATELLITE_NOT_REACHABLE = 18; // 0x12 - field public static final int SATELLITE_NOT_SUPPORTED = 20; // 0x14 - field public static final int SATELLITE_NO_RESOURCES = 12; // 0xc - field public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10; // 0xa - field public static final int SATELLITE_REQUEST_ABORTED = 15; // 0xf - field public static final int SATELLITE_REQUEST_FAILED = 9; // 0x9 - field public static final int SATELLITE_REQUEST_IN_PROGRESS = 21; // 0x15 - field public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11; // 0xb - field public static final int SATELLITE_SERVER_ERROR = 2; // 0x2 - field public static final int SATELLITE_SERVICE_ERROR = 3; // 0x3 - field public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13; // 0xd - field public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14; // 0xe + field public static final int SATELLITE_RESULT_ACCESS_BARRED = 16; // 0x10 + field public static final int SATELLITE_RESULT_ERROR = 1; // 0x1 + field public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8; // 0x8 + field public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7; // 0x7 + field public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6; // 0x6 + field public static final int SATELLITE_RESULT_MODEM_BUSY = 22; // 0x16 + field public static final int SATELLITE_RESULT_MODEM_ERROR = 4; // 0x4 + field public static final int SATELLITE_RESULT_NETWORK_ERROR = 5; // 0x5 + field public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17; // 0x11 + field public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19; // 0x13 + field public static final int SATELLITE_RESULT_NOT_REACHABLE = 18; // 0x12 + field public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20; // 0x14 + field public static final int SATELLITE_RESULT_NO_RESOURCES = 12; // 0xc + field public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10; // 0xa + field public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15; // 0xf + field public static final int SATELLITE_RESULT_REQUEST_FAILED = 9; // 0x9 + field public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21; // 0x15 + field public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11; // 0xb + field public static final int SATELLITE_RESULT_SERVER_ERROR = 2; // 0x2 + field public static final int SATELLITE_RESULT_SERVICE_ERROR = 3; // 0x3 + field public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13; // 0xd + field public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14; // 0xe + field public static final int SATELLITE_RESULT_SUCCESS = 0; // 0x0 } public static class SatelliteManager.SatelliteException extends java.lang.Exception { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 22d2999e9309..29b52132be75 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2247,6 +2247,10 @@ package android.os { method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void unplugBattery(boolean); } + public final class BugreportParams { + field public static final int BUGREPORT_MODE_MAX_VALUE = 7; // 0x7 + } + public class Build { method public static boolean is64BitAbi(String); method public static boolean isDebuggable(); @@ -2708,7 +2712,7 @@ package android.os.vibrator { package android.os.vibrator.persistence { public class ParsedVibration { - method @NonNull public java.util.List<android.os.VibrationEffect> getVibrationEffectListForTesting(); + method @NonNull public java.util.List<android.os.VibrationEffect> getVibrationEffects(); method @Nullable public android.os.VibrationEffect resolve(@NonNull android.os.Vibrator); } diff --git a/core/java/android/app/AppOps.md b/core/java/android/app/AppOps.md index 4589a71d5e5f..7b11a0351ebe 100644 --- a/core/java/android/app/AppOps.md +++ b/core/java/android/app/AppOps.md @@ -59,8 +59,8 @@ To control access the app-op can be set to: : Throw a `SecurityException` on access. This can be suppressed by using a `...noThrow` method to check the mode -The initial state of an app-op is defined in `AppOpsManager.sOpDefaultMode`. Confusingly the -initial state is often not `MODE_DEFAULT` +The initial state of an app-op is defined in its `AppOpInfo`. Confusingly the initial state is not +always `MODE_DEFAULT`, if `AppOpInfo.Builder.setDefaultMode()` is called with a different mode. Per-package modes can be set using `AppOpsManager.setMode` and per-uid modes can be set using `AppOpsManager.setUidMode`. diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 56fef1aac36a..dab4110279fe 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1486,13 +1486,13 @@ public class AppOpsManager { AppProtoEnums.APP_OP_RECEIVE_SANDBOX_TRIGGER_AUDIO; /** - * Allows the assistant app to get the negative trigger data from the PCC sandbox to improve the + * Allows the assistant app to get the training data from the PCC sandbox to improve the * hotword training model. * * @hide */ - public static final int OP_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO = - AppProtoEnums.APP_OP_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO; + public static final int OP_RECEIVE_SANDBOX_TRAINING_DATA = + AppProtoEnums.APP_OP_RECEIVE_SANDBOX_TRAINING_DATA; /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1640,7 +1640,7 @@ public class AppOpsManager { OPSTR_CAMERA_SANDBOXED, OPSTR_RECORD_AUDIO_SANDBOXED, OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO, - OPSTR_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO + OPSTR_RECEIVE_SANDBOX_TRAINING_DATA }) public @interface AppOpString {} @@ -2261,13 +2261,13 @@ public class AppOpsManager { "android:receive_sandbox_trigger_audio"; /** - * Allows the assistant app to get the negative trigger data from the PCC sandbox to improve + * Allows the assistant app to get the training data from the PCC sandbox to improve * the hotword training model. * * @hide */ - public static final String OPSTR_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO = - "android:receive_sandbox_negative_data_audio"; + public static final String OPSTR_RECEIVE_SANDBOX_TRAINING_DATA = + "android:receive_sandbox_training_data"; /** {@link #sAppOpsToNote} not initialized yet for this op */ private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0; @@ -2811,9 +2811,9 @@ public class AppOpsManager { OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO, "RECEIVE_SANDBOX_TRIGGER_AUDIO") .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(), - new AppOpInfo.Builder(OP_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO, - OPSTR_RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO, - "RECEIVE_SANDBOX_NEGATIVE_DATA_AUDIO").build() + new AppOpInfo.Builder(OP_RECEIVE_SANDBOX_TRAINING_DATA, + OPSTR_RECEIVE_SANDBOX_TRAINING_DATA, + "RECEIVE_SANDBOX_TRAINING_DATA").build() }; // The number of longs needed to form a full bitmask of app ops diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index d66fca8945f1..ed0f872bf9bc 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -2495,7 +2495,8 @@ public class AssistStructure implements Parcelable { + ", hints=" + Arrays.toString(node.getAutofillHints()) + ", value=" + node.getAutofillValue() + ", sanitized=" + node.isSanitized() - + ", important=" + node.getImportantForAutofill()); + + ", important=" + node.getImportantForAutofill() + + ", visibility=" + node.getVisibility()); } final int NCHILDREN = node.getChildCount(); diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl index 4801d155eb33..be699f4b9fa3 100644 --- a/core/java/android/companion/virtual/IVirtualDevice.aidl +++ b/core/java/android/companion/virtual/IVirtualDevice.aidl @@ -70,6 +70,12 @@ interface IVirtualDevice { void close(); /** + * Specifies a policy for this virtual device. + */ + @EnforcePermission("CREATE_VIRTUAL_DEVICE") + void setDevicePolicy(int policyType, int devicePolicy); + + /** * Notifies that an audio session being started. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java index d13bfd4f6229..2e5c0f77de4a 100644 --- a/core/java/android/companion/virtual/VirtualDeviceInternal.java +++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java @@ -238,6 +238,15 @@ public class VirtualDeviceInternal { } } + void setDevicePolicy(@VirtualDeviceParams.DynamicPolicyType int policyType, + @VirtualDeviceParams.DevicePolicy int devicePolicy) { + try { + mVirtualDevice.setDevicePolicy(policyType, devicePolicy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + @NonNull VirtualDpad createVirtualDpad(@NonNull VirtualDpadConfig config) { try { diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java index 060a5c85a713..923e68951509 100644 --- a/core/java/android/companion/virtual/VirtualDeviceManager.java +++ b/core/java/android/companion/virtual/VirtualDeviceManager.java @@ -19,6 +19,7 @@ package android.companion.virtual; import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; @@ -32,6 +33,7 @@ import android.app.PendingIntent; import android.companion.AssociationInfo; import android.companion.virtual.audio.VirtualAudioDevice; import android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback; +import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; import android.content.ComponentName; import android.content.Context; @@ -58,6 +60,8 @@ import android.os.RemoteException; import android.util.Log; import android.view.Surface; +import com.android.internal.util.AnnotationValidations; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -173,6 +177,9 @@ public final class VirtualDeviceManager { int associationId, @NonNull VirtualDeviceParams params) { Objects.requireNonNull(params, "params must not be null"); + if (Flags.moreLogs()) { + Log.i(TAG, "Creating VirtualDevice"); + } try { return new VirtualDevice(mService, mContext, associationId, params); } catch (RemoteException e) { @@ -509,6 +516,28 @@ public final class VirtualDeviceManager { } /** + * Specifies a policy for this virtual device. + * + * <p>Policies define the system behavior that may be specific for this virtual device. The + * given policy must be able to be changed dynamically during the lifetime of the device. + * + * @param policyType the type of policy, i.e. which behavior to specify a policy for. + * @param devicePolicy the value of the policy, i.e. how to interpret the device behavior. + * + * @see VirtualDeviceParams#POLICY_TYPE_RECENTS + */ + @FlaggedApi(Flags.FLAG_DYNAMIC_POLICY) + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void setDevicePolicy(@VirtualDeviceParams.DynamicPolicyType int policyType, + @VirtualDeviceParams.DevicePolicy int devicePolicy) { + AnnotationValidations.validate( + VirtualDeviceParams.DynamicPolicyType.class, null, policyType); + AnnotationValidations.validate( + VirtualDeviceParams.DevicePolicy.class, null, devicePolicy); + mVirtualDeviceInternal.setDevicePolicy(policyType, devicePolicy); + } + + /** * Creates a virtual dpad. * * @param config the configurations of the virtual dpad. diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java index b6d837589284..037e814a722d 100644 --- a/core/java/android/companion/virtual/VirtualDeviceParams.java +++ b/core/java/android/companion/virtual/VirtualDeviceParams.java @@ -150,6 +150,17 @@ public final class VirtualDeviceParams implements Parcelable { public @interface PolicyType {} /** + * Policy types that can be dynamically changed during the virtual device's lifetime. + * + * @see VirtualDeviceManager.VirtualDevice#setDevicePolicy + * @hide + */ + @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS}) + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) + public @interface DynamicPolicyType {} + + /** * Tells the sensor framework how to handle sensor requests from contexts associated with this * virtual device, namely the sensors returned by * {@link android.hardware.SensorManager#getSensorList}: @@ -375,6 +386,14 @@ public final class VirtualDeviceParams implements Parcelable { } /** + * Returns all device policies. + * @hide + */ + public @NonNull SparseIntArray getDevicePolicies() { + return mDevicePolicies; + } + + /** * Returns the configurations for all sensors that should be created for this device. * * @see Builder#addVirtualSensorConfig diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig new file mode 100644 index 000000000000..057b8565a8bb --- /dev/null +++ b/core/java/android/companion/virtual/flags.aconfig @@ -0,0 +1,15 @@ +package: "android.companion.virtual.flags" + +flag { + name: "more_logs" + namespace: "virtual_devices" + description: "More logs to test flags with" + bug: "291725823" +} + +flag { + name: "dynamic_policy" + namespace: "virtual_devices" + description: "Enable dynamic policy API" + bug: "298401780" +} diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java index 8f35ca25ab22..15678a772ef4 100644 --- a/core/java/android/content/AttributionSource.java +++ b/core/java/android/content/AttributionSource.java @@ -226,6 +226,11 @@ public final class AttributionSource implements Parcelable { } /** @hide */ + public AttributionSource withDefaultToken() { + return withToken(sDefaultToken); + } + + /** @hide */ public AttributionSource withPid(int pid) { return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext()); @@ -552,16 +557,28 @@ public final class AttributionSource implements Parcelable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AttributionSource that = (AttributionSource) o; - return mAttributionSourceState.uid == that.mAttributionSourceState.uid + return equalsExceptToken(that) && Objects.equals( + mAttributionSourceState.token, that.mAttributionSourceState.token); + } + + /** + * We store trusted attribution sources without their token (the token is the key to the map) + * to avoid having a strong reference to the token. This means, when checking the equality of a + * supplied AttributionSource in PermissionManagerService.isTrustedAttributionSource, we want to + * compare everything except the token. + * + * @hide + */ + public boolean equalsExceptToken(@Nullable AttributionSource o) { + if (o == null) return false; + return mAttributionSourceState.uid == o.mAttributionSourceState.uid && Objects.equals(mAttributionSourceState.packageName, - that.mAttributionSourceState.packageName) + o.mAttributionSourceState.packageName) && Objects.equals(mAttributionSourceState.attributionTag, - that.mAttributionSourceState.attributionTag) - && Objects.equals(mAttributionSourceState.token, - that.mAttributionSourceState.token) + o.mAttributionSourceState.attributionTag) && Arrays.equals(mAttributionSourceState.renouncedPermissions, - that.mAttributionSourceState.renouncedPermissions) - && Objects.equals(getNext(), that.getNext()); + o.mAttributionSourceState.renouncedPermissions) + && Objects.equals(getNext(), o.getNext()); } @Override diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 31f6418ac3d0..fe7d1e6fb232 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -5270,6 +5270,16 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_SHOW_FOREGROUND_SERVICE_MANAGER = "android.intent.action.SHOW_FOREGROUND_SERVICE_MANAGER"; + /** + * Broadcast Action: Sent to the responsible installer of an archived package when unarchival + * is requested. + * + * @see android.content.pm.PackageArchiver + * @hide + */ + @SystemApi + public static final String ACTION_UNARCHIVE_PACKAGE = "android.intent.action.UNARCHIVE_PACKAGE"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard intent categories (see addCategory()). diff --git a/core/java/android/content/pm/ArchivedPackageParcel.aidl b/core/java/android/content/pm/ArchivedPackageParcel.aidl new file mode 100644 index 000000000000..b34b708aa2c5 --- /dev/null +++ b/core/java/android/content/pm/ArchivedPackageParcel.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import android.content.pm.SigningDetails; + +/** + * Contains fields required for archived package installation, + * i.e. installation without an APK. + * @hide + */ +parcelable ArchivedPackageParcel { + String packageName; + SigningDetails signingDetails; + int versionCode; + int versionCodeMajor; + int targetSdkVersion; + boolean clearUserDataAllowed; + boolean backupAllowed; + boolean defaultToDeviceProtectedStorage; + boolean requestLegacyExternalStorage; + boolean userDataFragile; + boolean clearUserDataOnFailedRestoreAllowed; +} diff --git a/core/java/android/content/pm/IPackageArchiverService.aidl b/core/java/android/content/pm/IPackageArchiverService.aidl index fc471c451370..dc6491d6d97e 100644 --- a/core/java/android/content/pm/IPackageArchiverService.aidl +++ b/core/java/android/content/pm/IPackageArchiverService.aidl @@ -23,4 +23,7 @@ interface IPackageArchiverService { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.DELETE_PACKAGES,android.Manifest.permission.REQUEST_DELETE_PACKAGES})") void requestArchive(String packageName, String callerPackageName, in IntentSender statusReceiver, in UserHandle userHandle); + + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES,android.Manifest.permission.REQUEST_INSTALL_PACKAGES})") + void requestUnarchive(String packageName, String callerPackageName, in UserHandle userHandle); }
\ No newline at end of file diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 4ed4dd3c015a..916c249019a7 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ArchivedPackageParcel; import android.content.pm.ChangedPackages; import android.content.pm.InstantAppInfo; import android.content.pm.FeatureInfo; @@ -833,4 +834,6 @@ interface IPackageManager { void registerPackageMonitorCallback(IRemoteCallback callback, int userId); void unregisterPackageMonitorCallback(IRemoteCallback callback); + + ArchivedPackageParcel getArchivedPackage(in String apkPath); } diff --git a/core/java/android/content/pm/PackageArchiver.java b/core/java/android/content/pm/PackageArchiver.java index d739d5054800..b06523160b92 100644 --- a/core/java/android/content/pm/PackageArchiver.java +++ b/core/java/android/content/pm/PackageArchiver.java @@ -42,6 +42,26 @@ import android.os.RemoteException; @SystemApi public class PackageArchiver { + /** + * Extra field for the package name of a package that is requested to be unarchived. Sent as + * part of the {@link android.content.Intent#ACTION_UNARCHIVE_PACKAGE} intent. + * + * @hide + */ + @SystemApi + public static final String EXTRA_UNARCHIVE_PACKAGE_NAME = + "android.content.pm.extra.UNARCHIVE_PACKAGE_NAME"; + + /** + * If true, the requestor of the unarchival has specified that the app should be unarchived + * for {@link android.os.UserHandle#ALL}. + * + * @hide + */ + @SystemApi + public static final String EXTRA_UNARCHIVE_ALL_USERS = + "android.content.pm.extra.UNARCHIVE_ALL_USERS"; + private final Context mContext; private final IPackageArchiverService mService; @@ -58,7 +78,7 @@ public class PackageArchiver { * * @param statusReceiver Callback used to notify when the operation is completed. * @throws NameNotFoundException If {@code packageName} isn't found or not available to the - * caller. + * caller or isn't archived. * @hide */ @RequiresPermission(anyOf = { @@ -76,4 +96,34 @@ public class PackageArchiver { throw e.rethrowFromSystemServer(); } } + + /** + * Requests to unarchive a currently archived package. + * + * <p> Sends a request to unarchive an app to the responsible installer. The installer is + * determined by {@link InstallSourceInfo#getUpdateOwnerPackageName()}, or + * {@link InstallSourceInfo#getInstallingPackageName()} if the former value is null. + * + * <p> The installation will happen asynchronously and can be observed through + * {@link android.content.Intent#ACTION_PACKAGE_ADDED}. + * + * @throws NameNotFoundException If {@code packageName} isn't found or not visible to the + * caller or if the package has no installer on the device + * anymore to unarchive it. + * @hide + */ + @RequiresPermission(anyOf = { + Manifest.permission.INSTALL_PACKAGES, + Manifest.permission.REQUEST_INSTALL_PACKAGES}) + @SystemApi + public void requestUnarchive(@NonNull String packageName) + throws NameNotFoundException { + try { + mService.requestUnarchive(packageName, mContext.getPackageName(), mContext.getUser()); + } catch (ParcelableException e) { + e.maybeRethrow(NameNotFoundException.class); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index 63c11b779641..cdb8b46ba41a 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -488,6 +489,17 @@ public class PackageInfo implements Parcelable { */ public boolean isActiveApex; + /** + * Whether the package is currently in an archived state. + * + * <p>Packages can be archived through {@link PackageArchiver} and do not have any APKs stored + * on the device, but do keep the data directory. + * @hide + */ + // TODO(b/278553670) Unhide and update @links before launch. + @SystemApi + public boolean isArchived; + public PackageInfo() { } @@ -575,6 +587,7 @@ public class PackageInfo implements Parcelable { } dest.writeBoolean(isApex); dest.writeBoolean(isActiveApex); + dest.writeBoolean(isArchived); dest.restoreAllowSquashing(prevAllowSquashing); } @@ -640,5 +653,6 @@ public class PackageInfo implements Parcelable { } isApex = source.readBoolean(); isActiveApex = source.readBoolean(); + isArchived = source.readBoolean(); } } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index d2173a6d44bd..9a53a2a60076 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -787,6 +787,7 @@ public abstract class PackageManager { MATCH_DEBUG_TRIAGED_MISSING, MATCH_INSTANT, MATCH_APEX, + MATCH_ARCHIVED_PACKAGES, GET_DISABLED_COMPONENTS, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, @@ -811,6 +812,7 @@ public abstract class PackageManager { GET_UNINSTALLED_PACKAGES, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, MATCH_APEX, + MATCH_ARCHIVED_PACKAGES, }) @Retention(RetentionPolicy.SOURCE) public @interface ApplicationInfoFlagsBits {} @@ -1235,6 +1237,21 @@ public abstract class PackageManager { public static final long GET_ATTRIBUTIONS_LONG = 0x80000000L; /** + * Flag parameter to also retrieve some information about archived packages. + * Packages can be archived through {@link PackageArchiver} and do not have any APKs stored on + * the device, but do keep the data directory. + * <p> Note: Archived apps are a subset of apps returned by {@link #MATCH_UNINSTALLED_PACKAGES}. + * <p> Note: this flag may cause less information about currently installed + * applications to be returned. + * <p> Note: use of this flag requires the android.permission.QUERY_ALL_PACKAGES + * permission to see uninstalled packages. + * @hide + */ + // TODO(b/278553670) Unhide and update @links before launch. + @SystemApi + public static final long MATCH_ARCHIVED_PACKAGES = 1L << 32; + + /** * @hide */ public static final long FILTER_OUT_QUARANTINED_COMPONENTS = 0x100000000L; @@ -1682,6 +1699,13 @@ public abstract class PackageManager { public static final int INSTALL_FROM_MANAGED_USER_OR_PROFILE = 1 << 26; /** + * Flag parameter for {@link PackageInstaller.SessionParams} to indicate that this + * session is for archived package installation. + * @hide + */ + public static final int INSTALL_ARCHIVED = 1 << 27; + + /** * Flag parameter for {@link #installPackage} to force a non-staged update of an APEX. This is * a development-only feature and should not be used on end user devices. * diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/core/java/android/content/pm/SigningDetails.aidl index 24064b1261b7..95f3ca786c03 100644 --- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt +++ b/core/java/android/content/pm/SigningDetails.aidl @@ -13,14 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package android.content.pm; -package com.android.systemui.scene.ui.composable - -import com.android.systemui.scene.shared.model.Scene -import dagger.Module -import dagger.multibindings.Multibinds - -@Module -interface SceneModule { - @Multibinds fun scenes(): Set<Scene> -} +parcelable SigningDetails; diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING index ea21d51b0e9e..ab669cc141f1 100644 --- a/core/java/android/content/pm/TEST_MAPPING +++ b/core/java/android/content/pm/TEST_MAPPING @@ -48,9 +48,6 @@ "name":"CarrierAppIntegrationTestCases" }, { - "name":"ApkVerityTest" - }, - { "name":"CtsSilentUpdateHostTestCases" }, { diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java index 269bec256282..71cfd1b1e1cb 100644 --- a/core/java/android/content/pm/parsing/ApkLite.java +++ b/core/java/android/content/pm/parsing/ApkLite.java @@ -18,6 +18,7 @@ package android.content.pm.parsing; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ArchivedPackageParcel; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.SigningDetails; @@ -138,6 +139,39 @@ public class ApkLite { */ private final boolean mIsSdkLibrary; + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + private final boolean mClearUserDataAllowed; + + /** + * Set to <code>false</code> if the application does not wish to permit any OS-driven + * backups of its data; <code>true</code> otherwise. + */ + private final boolean mBackupAllowed; + + /** + * When set, the default data storage directory for this app is pointed at + * the device-protected location. + */ + private final boolean mDefaultToDeviceProtectedStorage; + + /** + * If {@code true} this app requests full external storage access. + */ + private final boolean mRequestLegacyExternalStorage; + + /** + * Indicates whether this application has declared its user data as fragile, causing the + * system to prompt the user on whether to keep the user data on uninstall. + */ + private final boolean mUserDataFragile; + + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + private final boolean mClearUserDataOnFailedRestoreAllowed; + public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit, String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode, int versionCodeMajor, int revisionCode, int installLocation, @@ -148,7 +182,10 @@ public class ApkLite { String requiredSystemPropertyName, String requiredSystemPropertyValue, int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy, Set<String> requiredSplitTypes, Set<String> splitTypes, - boolean hasDeviceAdminReceiver, boolean isSdkLibrary) { + boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean clearUserDataAllowed, + boolean backupAllowed, boolean defaultToDeviceProtectedStorage, + boolean requestLegacyExternalStorage, boolean userDataFragile, + boolean clearUserDataOnFailedRestoreAllowed) { mPath = path; mPackageName = packageName; mSplitName = splitName; @@ -182,6 +219,54 @@ public class ApkLite { mRollbackDataPolicy = rollbackDataPolicy; mHasDeviceAdminReceiver = hasDeviceAdminReceiver; mIsSdkLibrary = isSdkLibrary; + mClearUserDataAllowed = clearUserDataAllowed; + mBackupAllowed = backupAllowed; + mDefaultToDeviceProtectedStorage = defaultToDeviceProtectedStorage; + mRequestLegacyExternalStorage = requestLegacyExternalStorage; + mUserDataFragile = userDataFragile; + mClearUserDataOnFailedRestoreAllowed = clearUserDataOnFailedRestoreAllowed; + } + + public ApkLite(String path, ArchivedPackageParcel archivedPackage) { + mPath = path; + mPackageName = archivedPackage.packageName; + mSplitName = null; // base.apk + mSplitTypes = null; + mFeatureSplit = false; + mConfigForSplit = null; + mUsesSplitName = null; + mRequiredSplitTypes = null; + mSplitRequired = hasAnyRequiredSplitTypes(); + mVersionCode = archivedPackage.versionCode; + mVersionCodeMajor = archivedPackage.versionCodeMajor; + mRevisionCode = 0; + mInstallLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; + mVerifiers = new VerifierInfo[]{}; + mSigningDetails = archivedPackage.signingDetails; + mCoreApp = false; + mDebuggable = false; + mProfileableByShell = false; + mMultiArch = false; + mUse32bitAbi = false; + mUseEmbeddedDex = false; + mExtractNativeLibs = false; + mIsolatedSplits = false; + mTargetPackageName = null; + mOverlayIsStatic = false; + mOverlayPriority = 0; + mRequiredSystemPropertyName = null; + mRequiredSystemPropertyValue = null; + mMinSdkVersion = ApkLiteParseUtils.DEFAULT_MIN_SDK_VERSION; + mTargetSdkVersion = archivedPackage.targetSdkVersion; + mRollbackDataPolicy = 0; + mHasDeviceAdminReceiver = false; + mIsSdkLibrary = false; + mClearUserDataAllowed = archivedPackage.clearUserDataAllowed; + mBackupAllowed = archivedPackage.backupAllowed; + mDefaultToDeviceProtectedStorage = archivedPackage.defaultToDeviceProtectedStorage; + mRequestLegacyExternalStorage = archivedPackage.requestLegacyExternalStorage; + mUserDataFragile = archivedPackage.userDataFragile; + mClearUserDataOnFailedRestoreAllowed = archivedPackage.clearUserDataOnFailedRestoreAllowed; } /** @@ -474,6 +559,9 @@ public class ApkLite { return mRollbackDataPolicy; } + /** + * Indicates if this app contains a {@link android.app.admin.DeviceAdminReceiver}. + */ @DataClass.Generated.Member public boolean isHasDeviceAdminReceiver() { return mHasDeviceAdminReceiver; @@ -487,11 +575,62 @@ public class ApkLite { return mIsSdkLibrary; } + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + @DataClass.Generated.Member + public boolean isClearUserDataAllowed() { + return mClearUserDataAllowed; + } + + /** + * Set to <code>false</code> if the application does not wish to permit any OS-driven + * backups of its data; <code>true</code> otherwise. + */ + @DataClass.Generated.Member + public boolean isBackupAllowed() { + return mBackupAllowed; + } + + /** + * When set, the default data storage directory for this app is pointed at + * the device-protected location. + */ + @DataClass.Generated.Member + public boolean isDefaultToDeviceProtectedStorage() { + return mDefaultToDeviceProtectedStorage; + } + + /** + * If {@code true} this app requests full external storage access. + */ + @DataClass.Generated.Member + public boolean isRequestLegacyExternalStorage() { + return mRequestLegacyExternalStorage; + } + + /** + * Indicates whether this application has declared its user data as fragile, causing the + * system to prompt the user on whether to keep the user data on uninstall. + */ + @DataClass.Generated.Member + public boolean isUserDataFragile() { + return mUserDataFragile; + } + + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + @DataClass.Generated.Member + public boolean isClearUserDataOnFailedRestoreAllowed() { + return mClearUserDataOnFailedRestoreAllowed; + } + @DataClass.Generated( - time = 1643063342990L, + time = 1693422809896L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java", - inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mClearUserDataAllowed\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 4f6bcb6f0be5..066ff6896ac8 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -40,6 +40,7 @@ import android.util.Pair; import android.util.Slog; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.XmlUtils; import libcore.io.IoUtils; @@ -73,7 +74,7 @@ public class ApkLiteParseUtils { // Constants copied from services.jar side since they're not accessible private static final String ANDROID_RES_NAMESPACE = "http://schemas.android.com/apk/res/android"; - private static final int DEFAULT_MIN_SDK_VERSION = 1; + public static final int DEFAULT_MIN_SDK_VERSION = 1; private static final int DEFAULT_TARGET_SDK_VERSION = 0; public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml"; private static final int PARSE_IS_SYSTEM_DIR = 1 << 4; @@ -446,6 +447,13 @@ public class ApkLiteParseUtils { int overlayPriority = 0; int rollbackDataPolicy = 0; + boolean clearUserDataAllowed = true; + boolean backupAllowed = true; + boolean defaultToDeviceProtectedStorage = false; + String requestLegacyExternalStorage = null; + boolean userDataFragile = false; + boolean clearUserDataOnFailedRestoreAllowed = true; + String requiredSystemPropertyName = null; String requiredSystemPropertyValue = null; @@ -484,6 +492,23 @@ public class ApkLiteParseUtils { "extractNativeLibs", true); useEmbeddedDex = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, "useEmbeddedDex", false); + + clearUserDataAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, + "allowClearUserDataOnFailedRestore", true); + backupAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, + "allowBackup", true); + defaultToDeviceProtectedStorage = parser.getAttributeBooleanValue( + ANDROID_RES_NAMESPACE, + "defaultToDeviceProtectedStorage", false); + userDataFragile = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE, + "hasFragileUserData", false); + clearUserDataOnFailedRestoreAllowed = parser.getAttributeBooleanValue( + ANDROID_RES_NAMESPACE, + "allowClearUserDataOnFailedRestore", true); + + requestLegacyExternalStorage = parser.getAttributeValue(ANDROID_RES_NAMESPACE, + "requestLegacyExternalStorage"); + rollbackDataPolicy = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE, "rollbackDataPolicy", 0); String permission = parser.getAttributeValue(ANDROID_RES_NAMESPACE, @@ -604,6 +629,9 @@ public class ApkLiteParseUtils { return input.skip(message); } + boolean isRequestLegacyExternalStorage = XmlUtils.convertValueToBoolean( + requestLegacyExternalStorage, targetSdkVersion < Build.VERSION_CODES.Q); + return input.success( new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode, @@ -613,7 +641,9 @@ public class ApkLiteParseUtils { overlayIsStatic, overlayPriority, requiredSystemPropertyName, requiredSystemPropertyValue, minSdkVersion, targetSdkVersion, rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second, - hasDeviceAdminReceiver, isSdkLibrary)); + hasDeviceAdminReceiver, isSdkLibrary, clearUserDataAllowed, backupAllowed, + defaultToDeviceProtectedStorage, isRequestLegacyExternalStorage, + userDataFragile, clearUserDataOnFailedRestoreAllowed)); } private static boolean isDeviceAdminReceiver( diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java index e2789c93516f..4638af752d33 100644 --- a/core/java/android/content/pm/parsing/PackageLite.java +++ b/core/java/android/content/pm/parsing/PackageLite.java @@ -19,6 +19,7 @@ package android.content.pm.parsing; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.PackageInfo; +import android.content.pm.SigningDetails; import android.content.pm.VerifierInfo; import com.android.internal.util.ArrayUtils; @@ -78,6 +79,8 @@ public class PackageLite { private final int mInstallLocation; /** Information about a package verifiers as used during package verification */ private final @NonNull VerifierInfo[] mVerifiers; + /** Signing-related data of an application package */ + private final @NonNull SigningDetails mSigningDetails; /** Indicate whether any split APKs that are features. Ordered by splitName */ private final @Nullable boolean[] mIsFeatureSplits; @@ -109,6 +112,33 @@ public class PackageLite { * Indicates if this package is a sdk. */ private final boolean mIsSdkLibrary; + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + private final boolean mClearUserDataAllowed; + /** + * Set to <code>false</code> if the application does not wish to permit any OS-driven + * backups of its data; <code>true</code> otherwise. + */ + private final boolean mBackupAllowed; + /** + * When set, the default data storage directory for this app is pointed at + * the device-protected location. + */ + private final boolean mDefaultToDeviceProtectedStorage; + /** + * If {@code true} this app requests full external storage access. + */ + private final boolean mRequestLegacyExternalStorage; + /** + * Indicates whether this application has declared its user data as fragile, causing the + * system to prompt the user on whether to keep the user data on uninstall. + */ + private final boolean mUserDataFragile; + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + private final boolean mClearUserDataOnFailedRestoreAllowed; public PackageLite(String path, String baseApkPath, ApkLite baseApk, String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames, @@ -123,6 +153,7 @@ public class PackageLite { mVersionCodeMajor = baseApk.getVersionCodeMajor(); mInstallLocation = baseApk.getInstallLocation(); mVerifiers = baseApk.getVerifiers(); + mSigningDetails = baseApk.getSigningDetails(); mBaseRevisionCode = baseApk.getRevisionCode(); mCoreApp = baseApk.isCoreApp(); mDebuggable = baseApk.isDebuggable(); @@ -144,6 +175,12 @@ public class PackageLite { mSplitApkPaths = splitApkPaths; mSplitRevisionCodes = splitRevisionCodes; mTargetSdk = targetSdk; + mClearUserDataAllowed = baseApk.isClearUserDataAllowed(); + mBackupAllowed = baseApk.isBackupAllowed(); + mDefaultToDeviceProtectedStorage = baseApk.isDefaultToDeviceProtectedStorage(); + mRequestLegacyExternalStorage = baseApk.isRequestLegacyExternalStorage(); + mUserDataFragile = baseApk.isUserDataFragile(); + mClearUserDataOnFailedRestoreAllowed = baseApk.isClearUserDataOnFailedRestoreAllowed(); } /** @@ -325,6 +362,14 @@ public class PackageLite { } /** + * Signing-related data of an application package + */ + @DataClass.Generated.Member + public @NonNull SigningDetails getSigningDetails() { + return mSigningDetails; + } + + /** * Indicate whether any split APKs that are features. Ordered by splitName */ @DataClass.Generated.Member @@ -414,12 +459,62 @@ public class PackageLite { return mIsSdkLibrary; } + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + @DataClass.Generated.Member + public boolean isClearUserDataAllowed() { + return mClearUserDataAllowed; + } + + /** + * Set to <code>false</code> if the application does not wish to permit any OS-driven + * backups of its data; <code>true</code> otherwise. + */ + @DataClass.Generated.Member + public boolean isBackupAllowed() { + return mBackupAllowed; + } + + /** + * When set, the default data storage directory for this app is pointed at + * the device-protected location. + */ + @DataClass.Generated.Member + public boolean isDefaultToDeviceProtectedStorage() { + return mDefaultToDeviceProtectedStorage; + } + + /** + * If {@code true} this app requests full external storage access. + */ + @DataClass.Generated.Member + public boolean isRequestLegacyExternalStorage() { + return mRequestLegacyExternalStorage; + } + + /** + * Indicates whether this application has declared its user data as fragile, causing the + * system to prompt the user on whether to keep the user data on uninstall. + */ + @DataClass.Generated.Member + public boolean isUserDataFragile() { + return mUserDataFragile; + } + + /** + * Indicates whether this application's data will be cleared on a failed restore. + */ + @DataClass.Generated.Member + public boolean isClearUserDataOnFailedRestoreAllowed() { + return mClearUserDataOnFailedRestoreAllowed; + } + @DataClass.Generated( - time = 1643132127068L, + time = 1693423910860L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java", - inputSignatures = - "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") + inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final boolean mClearUserDataAllowed\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)") @Deprecated private void __metadata() {} diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 76b29e683312..5cc3b92da305 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -27,7 +27,6 @@ import android.annotation.PluralsRes; import android.annotation.RawRes; import android.annotation.StyleRes; import android.annotation.StyleableRes; -import android.app.ResourcesManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; @@ -430,49 +429,35 @@ public class ResourcesImpl { if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) { if (locales.size() > 1) { String[] availableLocales; - if (ResourcesManager.getInstance().getLocaleList().isEmpty()) { - // The LocaleList has changed. We must query the AssetManager's - // available Locales and figure out the best matching Locale in the new - // LocaleList. - availableLocales = mAssets.getNonSystemLocales(); + // The LocaleList has changed. We must query the AssetManager's + // available Locales and figure out the best matching Locale in the new + // LocaleList. + availableLocales = mAssets.getNonSystemLocales(); + if (LocaleList.isPseudoLocalesOnly(availableLocales)) { + // No app defined locales, so grab the system locales. + availableLocales = mAssets.getLocales(); if (LocaleList.isPseudoLocalesOnly(availableLocales)) { - // No app defined locales, so grab the system locales. - availableLocales = mAssets.getLocales(); - if (LocaleList.isPseudoLocalesOnly(availableLocales)) { - availableLocales = null; - } + availableLocales = null; } + } - if (availableLocales != null) { - final Locale bestLocale = locales.getFirstMatchWithEnglishSupported( - availableLocales); - if (bestLocale != null) { - selectedLocales = new String[]{ - adjustLanguageTag(bestLocale.toLanguageTag())}; - if (!bestLocale.equals(locales.get(0))) { - mConfiguration.setLocales( - new LocaleList(bestLocale, locales)); - } + if (availableLocales != null) { + final Locale bestLocale = locales.getFirstMatchWithEnglishSupported( + availableLocales); + if (bestLocale != null) { + selectedLocales = new String[]{ + adjustLanguageTag(bestLocale.toLanguageTag())}; + if (!bestLocale.equals(locales.get(0))) { + mConfiguration.setLocales( + new LocaleList(bestLocale, locales)); } } - } else { - selectedLocales = locales.getIntersection( - ResourcesManager.getInstance().getLocaleList()); - defaultLocale = ResourcesManager.getInstance() - .getLocaleList().get(0).toLanguageTag(); } } } if (selectedLocales == null) { - if (ResourcesManager.getInstance().getLocaleList().isEmpty()) { - selectedLocales = new String[]{ - adjustLanguageTag(locales.get(0).toLanguageTag())}; - } else { - selectedLocales = new String[locales.size()]; - for (int i = 0; i < locales.size(); i++) { - selectedLocales[i] = adjustLanguageTag(locales.get(i).toLanguageTag()); - } - } + selectedLocales = new String[]{ + adjustLanguageTag(locales.get(0).toLanguageTag())}; } if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) { diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index c0a44b178b66..f1ae9be8528d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -890,10 +890,13 @@ public class InputMethodService extends AbstractInputMethodService { mSystemCallingHideSoftInput = true; mCurHideInputToken = hideInputToken; mCurStatsToken = statsToken; - hideSoftInput(flags, resultReceiver); - mCurStatsToken = null; - mCurHideInputToken = null; - mSystemCallingHideSoftInput = false; + try { + hideSoftInput(flags, resultReceiver); + } finally { + mCurStatsToken = null; + mCurHideInputToken = null; + mSystemCallingHideSoftInput = false; + } } /** diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java index 7a153ef9c6f3..c5f56144c29c 100644 --- a/core/java/android/os/AggregateBatteryConsumer.java +++ b/core/java/android/os/AggregateBatteryConsumer.java @@ -116,8 +116,9 @@ public final class AggregateBatteryConsumer extends BatteryConsumer { * Builder for DeviceBatteryConsumer. */ public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> { - public Builder(BatteryConsumer.BatteryConsumerData data, int scope) { - super(data, CONSUMER_TYPE_AGGREGATE); + public Builder(BatteryConsumer.BatteryConsumerData data, int scope, + double minConsumedPowerThreshold) { + super(data, CONSUMER_TYPE_AGGREGATE, minConsumedPowerThreshold); data.putInt(COLUMN_INDEX_SCOPE, scope); } diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java index 0ba8d51e820f..ca84b3563561 100644 --- a/core/java/android/os/BatteryConsumer.java +++ b/core/java/android/os/BatteryConsumer.java @@ -795,11 +795,12 @@ public abstract class BatteryConsumer { protected final BatteryConsumer.BatteryConsumerData mData; protected final PowerComponents.Builder mPowerComponentsBuilder; - public BaseBuilder(BatteryConsumer.BatteryConsumerData data, int consumerType) { + public BaseBuilder(BatteryConsumer.BatteryConsumerData data, int consumerType, + double minConsumedPowerThreshold) { mData = data; data.putLong(COLUMN_INDEX_BATTERY_CONSUMER_TYPE, consumerType); - mPowerComponentsBuilder = new PowerComponents.Builder(data); + mPowerComponentsBuilder = new PowerComponents.Builder(data, minConsumedPowerThreshold); } @Nullable diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index 7586bf7700d9..a5f8844a2921 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -707,7 +707,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable { XML_ATTR_PREFIX_INCLUDES_PROC_STATE_DATA, false); builder = new Builder(customComponentNames.toArray(new String[0]), true, - includesProcStateData); + includesProcStateData, 0); builder.setStatsStartTimestamp( parser.getAttributeLong(null, XML_ATTR_START_TIMESTAMP)); @@ -782,6 +782,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable { private final String[] mCustomPowerComponentNames; private final boolean mIncludePowerModels; private final boolean mIncludesProcessStateData; + private final double mMinConsumedPowerThreshold; private final BatteryConsumer.BatteryConsumerDataLayout mBatteryConsumerDataLayout; private long mStatsStartTimestampMs; private long mStatsEndTimestampMs; @@ -802,11 +803,11 @@ public final class BatteryUsageStats implements Parcelable, Closeable { private BatteryStatsHistory mBatteryStatsHistory; public Builder(@NonNull String[] customPowerComponentNames) { - this(customPowerComponentNames, false, false); + this(customPowerComponentNames, false, false, 0); } public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels, - boolean includeProcessStateData) { + boolean includeProcessStateData, double minConsumedPowerThreshold) { mBatteryConsumersCursorWindow = new CursorWindow(null, BATTERY_CONSUMER_CURSOR_WINDOW_SIZE); mBatteryConsumerDataLayout = @@ -817,12 +818,14 @@ public final class BatteryUsageStats implements Parcelable, Closeable { mCustomPowerComponentNames = customPowerComponentNames; mIncludePowerModels = includePowerModels; mIncludesProcessStateData = includeProcessStateData; + mMinConsumedPowerThreshold = minConsumedPowerThreshold; for (int scope = 0; scope < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; scope++) { final BatteryConsumer.BatteryConsumerData data = BatteryConsumer.BatteryConsumerData.create(mBatteryConsumersCursorWindow, mBatteryConsumerDataLayout); mAggregateBatteryConsumersBuilders[scope] = - new AggregateBatteryConsumer.Builder(data, scope); + new AggregateBatteryConsumer.Builder( + data, scope, mMinConsumedPowerThreshold); } } @@ -961,7 +964,8 @@ public final class BatteryUsageStats implements Parcelable, Closeable { final BatteryConsumer.BatteryConsumerData data = BatteryConsumer.BatteryConsumerData.create(mBatteryConsumersCursorWindow, mBatteryConsumerDataLayout); - builder = new UidBatteryConsumer.Builder(data, batteryStatsUid); + builder = new UidBatteryConsumer.Builder(data, batteryStatsUid, + mMinConsumedPowerThreshold); mUidBatteryConsumerBuilders.put(uid, builder); } return builder; @@ -979,7 +983,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable { final BatteryConsumer.BatteryConsumerData data = BatteryConsumer.BatteryConsumerData.create(mBatteryConsumersCursorWindow, mBatteryConsumerDataLayout); - builder = new UidBatteryConsumer.Builder(data, uid); + builder = new UidBatteryConsumer.Builder(data, uid, mMinConsumedPowerThreshold); mUidBatteryConsumerBuilders.put(uid, builder); } return builder; @@ -996,7 +1000,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable { final BatteryConsumer.BatteryConsumerData data = BatteryConsumer.BatteryConsumerData.create(mBatteryConsumersCursorWindow, mBatteryConsumerDataLayout); - builder = new UserBatteryConsumer.Builder(data, userId); + builder = new UserBatteryConsumer.Builder(data, userId, mMinConsumedPowerThreshold); mUserBatteryConsumerBuilders.put(userId, builder); } return builder; diff --git a/core/java/android/os/BatteryUsageStatsQuery.java b/core/java/android/os/BatteryUsageStatsQuery.java index b3f4d9874f4e..49d7e8bc5632 100644 --- a/core/java/android/os/BatteryUsageStatsQuery.java +++ b/core/java/android/os/BatteryUsageStatsQuery.java @@ -80,6 +80,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { private final long mMaxStatsAgeMs; private final long mFromTimestamp; private final long mToTimestamp; + private final double mMinConsumedPowerThreshold; private final @BatteryConsumer.PowerComponent int[] mPowerComponents; private BatteryUsageStatsQuery(@NonNull Builder builder) { @@ -87,6 +88,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { mUserIds = builder.mUserIds != null ? builder.mUserIds.toArray() : new int[]{UserHandle.USER_ALL}; mMaxStatsAgeMs = builder.mMaxStatsAgeMs; + mMinConsumedPowerThreshold = builder.mMinConsumedPowerThreshold; mFromTimestamp = builder.mFromTimestamp; mToTimestamp = builder.mToTimestamp; mPowerComponents = builder.mPowerComponents; @@ -137,6 +139,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { } /** + * Returns the minimal power component consumed power threshold. The small power consuming + * components will be reported as zero. + */ + public double getMinConsumedPowerThreshold() { + return mMinConsumedPowerThreshold; + } + + /** * Returns the exclusive lower bound of the stored snapshot timestamps that should be included * in the aggregation. Ignored if {@link #getToTimestamp()} is zero. */ @@ -158,6 +168,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { mUserIds = new int[in.readInt()]; in.readIntArray(mUserIds); mMaxStatsAgeMs = in.readLong(); + mMinConsumedPowerThreshold = in.readDouble(); mFromTimestamp = in.readLong(); mToTimestamp = in.readLong(); mPowerComponents = in.createIntArray(); @@ -169,6 +180,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { dest.writeInt(mUserIds.length); dest.writeIntArray(mUserIds); dest.writeLong(mMaxStatsAgeMs); + dest.writeDouble(mMinConsumedPowerThreshold); dest.writeLong(mFromTimestamp); dest.writeLong(mToTimestamp); dest.writeIntArray(mPowerComponents); @@ -202,6 +214,7 @@ public final class BatteryUsageStatsQuery implements Parcelable { private long mMaxStatsAgeMs = DEFAULT_MAX_STATS_AGE_MS; private long mFromTimestamp; private long mToTimestamp; + private double mMinConsumedPowerThreshold = 0; private @BatteryConsumer.PowerComponent int[] mPowerComponents; /** @@ -301,5 +314,14 @@ public final class BatteryUsageStatsQuery implements Parcelable { mMaxStatsAgeMs = maxStatsAgeMs; return this; } + + /** + * Set the minimal power component consumed power threshold. The small power consuming + * components will be reported as zero. + */ + public Builder setMinConsumedPowerThreshold(double minConsumedPowerThreshold) { + mMinConsumedPowerThreshold = minConsumedPowerThreshold; + return this; + } } } diff --git a/core/java/android/os/BugreportParams.java b/core/java/android/os/BugreportParams.java index 0456a33580cf..f10467f0760e 100644 --- a/core/java/android/os/BugreportParams.java +++ b/core/java/android/os/BugreportParams.java @@ -18,6 +18,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.annotation.TestApi; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -127,6 +128,13 @@ public final class BugreportParams { public static final int BUGREPORT_MODE_ONBOARDING = IDumpstate.BUGREPORT_MODE_ONBOARDING; /** + * The maximum value of supported bugreport mode. + * @hide + */ + @TestApi + public static final int BUGREPORT_MODE_MAX_VALUE = BUGREPORT_MODE_ONBOARDING; + + /** * Defines acceptable flags for customizing bugreport requests. * @hide */ diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl index 62753527929c..f30dd20d7087 100644 --- a/core/java/android/os/IVibratorManagerService.aidl +++ b/core/java/android/os/IVibratorManagerService.aidl @@ -36,4 +36,10 @@ interface IVibratorManagerService { void vibrate(int uid, int displayId, String opPkg, in CombinedVibration vibration, in VibrationAttributes attributes, String reason, IBinder token); void cancelVibrate(int usageFilter, IBinder token); + + // Async oneway APIs. + // There is no order guarantee with respect to the two-way APIs above like + // vibrate/isVibrating/cancel. + oneway void performHapticFeedback(int uid, int displayId, String opPkg, int constant, + boolean always, String reason, IBinder token); } diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java index 5dffa0a0ac34..9e5f5399301c 100644 --- a/core/java/android/os/PowerComponents.java +++ b/core/java/android/os/PowerComponents.java @@ -461,9 +461,11 @@ class PowerComponents { private static final byte POWER_MODEL_UNINITIALIZED = -1; private final BatteryConsumer.BatteryConsumerData mData; + private final double mMinConsumedPowerThreshold; - Builder(BatteryConsumer.BatteryConsumerData data) { + Builder(BatteryConsumer.BatteryConsumerData data, double minConsumedPowerThreshold) { mData = data; + mMinConsumedPowerThreshold = minConsumedPowerThreshold; for (BatteryConsumer.Key[] keys : mData.layout.keys) { for (BatteryConsumer.Key key : keys) { if (key.mPowerModelColumnIndex != -1) { @@ -476,6 +478,9 @@ class PowerComponents { @NonNull public Builder setConsumedPower(BatteryConsumer.Key key, double componentPower, int powerModel) { + if (Math.abs(componentPower) < mMinConsumedPowerThreshold) { + componentPower = 0; + } mData.putDouble(key.mPowerColumnIndex, componentPower); if (key.mPowerModelColumnIndex != -1) { mData.putInt(key.mPowerModelColumnIndex, powerModel); @@ -491,6 +496,9 @@ class PowerComponents { */ @NonNull public Builder setConsumedPowerForCustomComponent(int componentId, double componentPower) { + if (Math.abs(componentPower) < mMinConsumedPowerThreshold) { + componentPower = 0; + } final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID; if (index < 0 || index >= mData.layout.customPowerComponentCount) { throw new IllegalArgumentException( diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java index 1cd0f3b156c2..04c257b92e29 100644 --- a/core/java/android/os/SystemVibrator.java +++ b/core/java/android/os/SystemVibrator.java @@ -206,6 +206,15 @@ public class SystemVibrator extends Vibrator { } @Override + public void performHapticFeedback(int constant, boolean always, String reason) { + if (mVibratorManager == null) { + Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager."); + return; + } + mVibratorManager.performHapticFeedback(constant, always, reason); + } + + @Override public void cancel() { if (mVibratorManager == null) { Log.w(TAG, "Failed to cancel vibrate; no vibrator manager."); diff --git a/core/java/android/os/SystemVibratorManager.java b/core/java/android/os/SystemVibratorManager.java index 284b2464c468..ee90834c15ef 100644 --- a/core/java/android/os/SystemVibratorManager.java +++ b/core/java/android/os/SystemVibratorManager.java @@ -145,6 +145,21 @@ public class SystemVibratorManager extends VibratorManager { } @Override + public void performHapticFeedback(int constant, boolean always, String reason) { + if (mService == null) { + Log.w(TAG, "Failed to perform haptic feedback; no vibrator manager service."); + return; + } + try { + mService.performHapticFeedback( + Process.myUid(), mContext.getAssociatedDisplayId(), mPackageName, constant, + always, reason, mToken); + } catch (RemoteException e) { + Log.w(TAG, "Failed to perform haptic feedback.", e); + } + } + + @Override public void cancel() { cancelVibration(VibrationAttributes.USAGE_FILTER_MATCH_ALL); } @@ -228,6 +243,11 @@ public class SystemVibratorManager extends VibratorManager { } @Override + public void performHapticFeedback(int effectId, boolean always, String reason) { + SystemVibratorManager.this.performHapticFeedback(effectId, always, reason); + } + + @Override public void cancel() { SystemVibratorManager.this.cancel(); } diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java index 103452d255a7..03a1b6f7fe01 100644 --- a/core/java/android/os/UidBatteryConsumer.java +++ b/core/java/android/os/UidBatteryConsumer.java @@ -207,17 +207,18 @@ public final class UidBatteryConsumer extends BatteryConsumer { private String mPackageWithHighestDrain = PACKAGE_NAME_UNINITIALIZED; private boolean mExcludeFromBatteryUsageStats; - public Builder(BatteryConsumerData data, @NonNull BatteryStats.Uid batteryStatsUid) { - this(data, batteryStatsUid, batteryStatsUid.getUid()); + public Builder(BatteryConsumerData data, @NonNull BatteryStats.Uid batteryStatsUid, + double minConsumedPowerThreshold) { + this(data, batteryStatsUid, batteryStatsUid.getUid(), minConsumedPowerThreshold); } - public Builder(BatteryConsumerData data, int uid) { - this(data, null, uid); + public Builder(BatteryConsumerData data, int uid, double minConsumedPowerThreshold) { + this(data, null, uid, minConsumedPowerThreshold); } private Builder(BatteryConsumerData data, @Nullable BatteryStats.Uid batteryStatsUid, - int uid) { - super(data, CONSUMER_TYPE_UID); + int uid, double minConsumedPowerThreshold) { + super(data, CONSUMER_TYPE_UID, minConsumedPowerThreshold); mBatteryStatsUid = batteryStatsUid; mUid = uid; mIsVirtualUid = mUid == Process.SDK_SANDBOX_VIRTUAL_UID; diff --git a/core/java/android/os/UserBatteryConsumer.java b/core/java/android/os/UserBatteryConsumer.java index 6b4a5cfc836f..a2ff078263ca 100644 --- a/core/java/android/os/UserBatteryConsumer.java +++ b/core/java/android/os/UserBatteryConsumer.java @@ -107,8 +107,8 @@ public class UserBatteryConsumer extends BatteryConsumer { public static final class Builder extends BaseBuilder<Builder> { private List<UidBatteryConsumer.Builder> mUidBatteryConsumers; - Builder(BatteryConsumerData data, int userId) { - super(data, CONSUMER_TYPE_USER); + Builder(BatteryConsumerData data, int userId, double minConsumedPowerThreshold) { + super(data, CONSUMER_TYPE_USER, minConsumedPowerThreshold); data.putLong(COLUMN_INDEX_USER_ID, userId); } diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index bcde31acda2e..c6cb604d4039 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1002,6 +1002,24 @@ public class UserManager { public static final String DISALLOW_ADD_CLONE_PROFILE = "no_add_clone_profile"; /** + * Specifies if a user is disallowed from creating a private profile. + * <p>The default value for an unmanaged user is <code>false</code>. + * For users with a device owner set, the default is <code>true</code>. + * + * <p>Holders of the permission + * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILES} + * can set this restriction using the DevicePolicyManager APIs mentioned below. + * + * <p>Key for user restrictions. + * <p>Type: Boolean + * @see DevicePolicyManager#addUserRestriction(ComponentName, String) + * @see DevicePolicyManager#clearUserRestriction(ComponentName, String) + * @see #getUserRestrictions() + * @hide + */ + public static final String DISALLOW_ADD_PRIVATE_PROFILE = "no_add_private_profile"; + + /** * Specifies if a user is disallowed from disabling application verification. The default * value is <code>false</code>. * @@ -1895,6 +1913,7 @@ public class UserManager { DISALLOW_ADD_USER, DISALLOW_ADD_MANAGED_PROFILE, DISALLOW_ADD_CLONE_PROFILE, + DISALLOW_ADD_PRIVATE_PROFILE, ENSURE_VERIFY_APPS, DISALLOW_CONFIG_CELL_BROADCASTS, DISALLOW_CONFIG_MOBILE_NETWORKS, diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java index aafa5018af10..99c9925d9cb7 100644 --- a/core/java/android/os/Vibrator.java +++ b/core/java/android/os/Vibrator.java @@ -510,6 +510,28 @@ public abstract class Vibrator { String reason, @NonNull VibrationAttributes attributes); /** + * Performs a haptic feedback. + * + * <p>A haptic feedback is a short vibration feedback. The type of feedback is identified via + * the {@code constant}, which should be one of the effect constants provided in + * {@link HapticFeedbackConstants}. The haptic feedback provided for a given effect ID is + * consistent across all usages on the same device. + * + * @param constant the ID for the haptic feedback. This should be one of the constants defined + * in {@link HapticFeedbackConstants}. + * @param always {@code true} if the haptic feedback should be played regardless of the user + * vibration intensity settings applicable to the corresponding vibration. + * {@code false} if the vibration for the haptic feedback should respect the applicable + * vibration intensity settings. + * @param reason the reason for this haptic feedback. + * + * @hide + */ + public void performHapticFeedback(int constant, boolean always, String reason) { + Log.w(TAG, "performHapticFeedback is not supported"); + } + + /** * Query whether the vibrator natively supports the given effects. * * <p>If an effect is not supported, the system may still automatically fall back to playing diff --git a/core/java/android/os/VibratorManager.java b/core/java/android/os/VibratorManager.java index f506ef8955d4..e0b6a9fd28f0 100644 --- a/core/java/android/os/VibratorManager.java +++ b/core/java/android/os/VibratorManager.java @@ -35,7 +35,8 @@ import android.util.Log; public abstract class VibratorManager { private static final String TAG = "VibratorManager"; - private final String mPackageName; + /** @hide */ + protected final String mPackageName; /** * @hide to prevent subclassing from outside of the framework @@ -137,6 +138,21 @@ public abstract class VibratorManager { String reason, @Nullable VibrationAttributes attributes); /** + * Performs a haptic feedback. + * + * @param constant the ID of the requested haptic feedback. Should be one of the constants + * defined in {@link HapticFeedbackConstants}. + * @param always {@code true} if the haptic feedback should be played regardless of the user + * vibration intensity settings applicable to the corresponding vibration. + * {@code false} otherwise. + * @param reason the reason for this haptic feedback. + * @hide + */ + public void performHapticFeedback(int constant, boolean always, String reason) { + Log.w(TAG, "performHapticFeedback is not supported"); + } + + /** * Turn all the vibrators off. */ @RequiresPermission(android.Manifest.permission.VIBRATE) diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig new file mode 100644 index 000000000000..361e244ac876 --- /dev/null +++ b/core/java/android/os/vibrator/flags.aconfig @@ -0,0 +1,8 @@ +package: "android.os.vibrator" + +flag { + namespace: "vibrator" + name: "use_vibrator_haptic_feedback" + description: "Enables performHapticFeedback to directly use the vibrator service instead of going through the window session" + bug: "295459081" +}
\ No newline at end of file diff --git a/core/java/android/os/vibrator/persistence/ParsedVibration.java b/core/java/android/os/vibrator/persistence/ParsedVibration.java index a76f597252ec..ded74eab149e 100644 --- a/core/java/android/os/vibrator/persistence/ParsedVibration.java +++ b/core/java/android/os/vibrator/persistence/ParsedVibration.java @@ -70,7 +70,7 @@ public class ParsedVibration { @TestApi @VisibleForTesting @NonNull - public List<VibrationEffect> getVibrationEffectListForTesting() { + public List<VibrationEffect> getVibrationEffects() { return Collections.unmodifiableList(mEffects); } diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java index 2a4c01e1c46e..1f798baf1bd6 100644 --- a/core/java/android/permission/PermissionUsageHelper.java +++ b/core/java/android/permission/PermissionUsageHelper.java @@ -87,11 +87,6 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis "location_indicators_enabled"; /** - * Whether to show the Permissions Hub. - */ - private static final String PROPERTY_PERMISSIONS_HUB_2_ENABLED = "permissions_hub_2_enabled"; - - /** * How long after an access to show it as "recent" */ private static final String RECENT_ACCESS_TIME_MS = "recent_access_time_ms"; @@ -106,14 +101,9 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis private static final long DEFAULT_RUNNING_TIME_MS = 5000L; private static final long DEFAULT_RECENT_TIME_MS = 15000L; - private static boolean shouldShowPermissionsHub() { - return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_PERMISSIONS_HUB_2_ENABLED, false); - } - private static boolean shouldShowIndicators() { return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_CAMERA_MIC_ICONS_ENABLED, true) || shouldShowPermissionsHub(); + PROPERTY_CAMERA_MIC_ICONS_ENABLED, true); } private static boolean shouldShowLocationIndicator() { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c3c802b8cf8d..82756af54c13 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2831,7 +2831,7 @@ public final class Settings { /** @hide - Private call() method to query the 'global' table */ public static final String CALL_METHOD_LIST_GLOBAL = "LIST_global"; - /** @hide - Private call() method to reset to defaults the 'configuration' table */ + /** @hide - Private call() method to query the 'configuration' table */ public static final String CALL_METHOD_LIST_CONFIG = "LIST_config"; /** @hide - Private call() method to disable / re-enable syncs to the 'configuration' table */ @@ -10664,20 +10664,6 @@ public final class Settings { "search_press_hold_nav_handle_enabled"; /** - * Control whether Trust Agents are in active unlock or extend unlock mode. - * @hide - */ - @Readable - public static final String TRUST_AGENTS_EXTEND_UNLOCK = "trust_agents_extend_unlock"; - - /** - * Control whether the screen locks when trust is lost. - * @hide - */ - @Readable - public static final String LOCK_SCREEN_WHEN_TRUST_LOST = "lock_screen_when_trust_lost"; - - /** * Control whether Night display is currently activated. * @hide */ @@ -18360,24 +18346,28 @@ public final class Settings { * If hotword detection should be enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String HOTWORD_DETECTION_ENABLED = "hotword_detection_enabled"; /** * Whether Smart Replies are enabled within Wear. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SMART_REPLIES_ENABLED = "smart_replies_enabled"; /** * The default vibration pattern. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String DEFAULT_VIBRATION = "default_vibration"; /** * If FLP should obtain location data from the paired device. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String OBTAIN_PAIRED_DEVICE_LOCATION = "obtain_paired_device_location"; @@ -18385,6 +18375,7 @@ public final class Settings { * The play store availability on companion phone. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String PHONE_PLAY_STORE_AVAILABILITY = "phone_play_store_availability"; @@ -18400,6 +18391,7 @@ public final class Settings { * Whether the bug report is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String BUG_REPORT = "bug_report"; // Possible bug report states @@ -18412,12 +18404,14 @@ public final class Settings { * The enabled/disabled state of the SmartIlluminate. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SMART_ILLUMINATE_ENABLED = "smart_illuminate_enabled"; /** * Whether automatic time is enabled on the watch. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CLOCKWORK_AUTO_TIME = "clockwork_auto_time"; // Possible clockwork auto time states @@ -18435,6 +18429,7 @@ public final class Settings { * Whether automatic time zone is enabled on the watch. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CLOCKWORK_AUTO_TIME_ZONE = "clockwork_auto_time_zone"; // Possible clockwork auto time zone states @@ -18451,12 +18446,14 @@ public final class Settings { * Whether 24 hour time format is enabled on the watch. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CLOCKWORK_24HR_TIME = "clockwork_24hr_time"; /** * Whether the auto wifi toggle setting is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AUTO_WIFI = "auto_wifi"; // Possible force wifi on states @@ -18476,6 +18473,7 @@ public final class Settings { * wifi requirement until this time). The time is in millis since epoch. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String ALT_BYPASS_WIFI_REQUIREMENT_TIME_MILLIS = "alt_bypass_wifi_requirement_time_millis"; @@ -18483,6 +18481,7 @@ public final class Settings { * Whether the setup was skipped. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SETUP_SKIPPED = "setup_skipped"; // Possible setup_skipped states @@ -18497,6 +18496,7 @@ public final class Settings { * The last requested call forwarding action. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String LAST_CALL_FORWARD_ACTION = "last_call_forward_action"; // Possible call forwarding actions @@ -18509,22 +18509,31 @@ public final class Settings { // Stem button settings. /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_1_TYPE = "STEM_1_TYPE"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_1_DATA = "STEM_1_DATA"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_1_DEFAULT_DATA = "STEM_1_DEFAULT_DATA"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_2_TYPE = "STEM_2_TYPE"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_2_DATA = "STEM_2_DATA"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_2_DEFAULT_DATA = "STEM_2_DEFAULT_DATA"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_3_TYPE = "STEM_3_TYPE"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_3_DATA = "STEM_3_DATA"; /** @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String STEM_3_DEFAULT_DATA = "STEM_3_DEFAULT_DATA"; // Stem types @@ -18539,12 +18548,14 @@ public final class Settings { * If the device should be muted when off body. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String MUTE_WHEN_OFF_BODY_ENABLED = "obtain_mute_when_off_body"; /** * Wear OS version string. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WEAR_OS_VERSION_STRING = "wear_os_version_string"; /** @@ -18557,24 +18568,28 @@ public final class Settings { * The android wear system version. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String ANDROID_WEAR_VERSION = "android_wear_version"; /** * The wear system capabiltiies. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SYSTEM_CAPABILITIES = "system_capabilities"; /** * The android wear system edition. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SYSTEM_EDITION = "android_wear_system_edition"; /** * The Wear platform MR number. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WEAR_PLATFORM_MR_NUMBER = "wear_platform_mr_number"; /** @@ -18588,36 +18603,42 @@ public final class Settings { * Whether ambient is currently enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_ENABLED = "ambient_enabled"; /** * Whether ambient tilt to wake is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_TILT_TO_WAKE = "ambient_tilt_to_wake"; /** * Whether ambient low bit mode is enabled by developer options. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_LOW_BIT_ENABLED_DEV = "ambient_low_bit_enabled_dev"; /** * Whether ambient touch to wake is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_TOUCH_TO_WAKE = "ambient_touch_to_wake"; /** * Whether ambient tilt to bright is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_TILT_TO_BRIGHT = "ambient_tilt_to_bright"; /** * Whether touch and hold to edit WF is enabled * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED = "gesture_touch_and_hold_watchface_enabled"; @@ -18631,6 +18652,7 @@ public final class Settings { * Whether bedtime mode is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String BEDTIME_MODE = "bedtime_mode"; /** @@ -18642,31 +18664,35 @@ public final class Settings { * Whether the current watchface is decomposable. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String DECOMPOSABLE_WATCHFACE = "current_watchface_decomposable"; /** * Whether to force ambient when docked. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_FORCE_WHEN_DOCKED = "ambient_force_when_docked"; /** * Whether the ambient low bit mode is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_LOW_BIT_ENABLED = "ambient_low_bit_enabled"; /** * The timeout duration in minutes of ambient mode when plugged in. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String AMBIENT_PLUGGED_TIMEOUT_MIN = "ambient_plugged_timeout_min"; /** * What OS does paired device has. * @hide */ - @Readable + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String PAIRED_DEVICE_OS_TYPE = "paired_device_os_type"; // Possible values of PAIRED_DEVICE_OS_TYPE @@ -18699,6 +18725,7 @@ public final class Settings { * The user's last setting for hfp client. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String USER_HFP_CLIENT_SETTING = "user_hfp_client_setting"; // Possible hfp client user setting values @@ -18723,6 +18750,7 @@ public final class Settings { * The companion App name. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String COMPANION_APP_NAME = "wear_companion_app_name"; /** @@ -18730,18 +18758,21 @@ public final class Settings { * wear. 1 for supporting, 0 for not supporting. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String ENABLE_ALL_LANGUAGES = "enable_all_languages"; /** * The Locale (as language tag) the user chose at startup. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String SETUP_LOCALE = "setup_locale"; /** * The version of oem setup present. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String OEM_SETUP_VERSION = "oem_setup_version"; /** @@ -18787,6 +18818,7 @@ public final class Settings { * -{@link BATTERY_SAVER_MODE_CUSTOM} * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String BATTERY_SAVER_MODE = "battery_saver_mode"; /** @@ -18819,6 +18851,7 @@ public final class Settings { * The maximum ambient mode duration when an activity is allowed to auto resume. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS = "wear_activity_auto_resume_timeout_ms"; @@ -18834,6 +18867,7 @@ public final class Settings { * If burn in protection is enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String BURN_IN_PROTECTION_ENABLED = "burn_in_protection"; /** @@ -18852,6 +18886,7 @@ public final class Settings { * RIGHT_WRIST_ROTATION_0 = "2", RIGHT_WRIST_ROTATION_180 = "3" * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WRIST_ORIENTATION_MODE = "wear_wrist_orientation_mode"; /** @@ -18890,6 +18925,7 @@ public final class Settings { * * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CLOCKWORK_SYSUI_PACKAGE = "clockwork_sysui_package"; /** @@ -18919,6 +18955,7 @@ public final class Settings { * Whether the device has Wet Mode/ Touch Lock Mode enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WET_MODE_ON = "wet_mode_on"; /** @@ -18937,6 +18974,7 @@ public final class Settings { * Whether charging sounds are enabled. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CHARGING_SOUNDS_ENABLED = "wear_charging_sounds_enabled"; /** @@ -18945,6 +18983,7 @@ public final class Settings { * * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String DYNAMIC_COLOR_THEME_ENABLED = "dynamic_color_theme_enabled"; /** @@ -19036,6 +19075,7 @@ public final class Settings { * The key to indicate the data migration status on device upgrade in Wear Services. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String UPGRADE_DATA_MIGRATION_STATUS = "upgrade_data_migration_status"; @@ -19086,17 +19126,20 @@ public final class Settings { * The custom foreground color. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CUSTOM_COLOR_FOREGROUND = "custom_foreground_color"; /** * The custom background color. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String CUSTOM_COLOR_BACKGROUND = "custom_background_color"; /** The status of the phone switching process. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String PHONE_SWITCHING_STATUS = "phone_switching_status"; /** @@ -19177,6 +19220,7 @@ public final class Settings { * (0 = false, 1 = true) * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String REDUCE_MOTION = "reduce_motion"; /** @@ -19238,6 +19282,7 @@ public final class Settings { * Controls the launcher ui mode on wearable devices. * @hide */ + @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public static final String WEAR_LAUNCHER_UI_MODE = "wear_launcher_ui_mode"; /** Whether Wear Power Anomaly Service is enabled. @@ -19364,6 +19409,36 @@ public final class Settings { } /** + * Return all stored flags. + * + * The keys take the form {@code namespace/flag}, and the values are the flag values. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @NonNull + public static Map<String, String> getAllStrings() { + HashMap<String, String> allFlags = new HashMap<String, String>(); + try { + ContentResolver resolver = getContentResolver(); + Bundle arg = new Bundle(); + arg.putInt(Settings.CALL_METHOD_USER_KEY, resolver.getUserId()); + IContentProvider cp = sProviderHolder.getProvider(resolver); + Bundle b = cp.call(resolver.getAttributionSource(), + sProviderHolder.mUri.getAuthority(), CALL_METHOD_LIST_CONFIG, null, arg); + if (b != null) { + Map<String, String> flagsToValues = + (HashMap) b.getSerializable(Settings.NameValueTable.VALUE, + java.util.HashMap.class); + allFlags.putAll(flagsToValues); + } + } catch (RemoteException e) { + Log.w(TAG, "Can't query configuration table for " + CONTENT_URI, e); + } + return allFlags; + } + + /** * Look up a list of names in the database, within the specified namespace. * * @param resolver to access the database with diff --git a/core/java/android/security/FileIntegrityManager.java b/core/java/android/security/FileIntegrityManager.java index 7869404c265f..132700d289b8 100644 --- a/core/java/android/security/FileIntegrityManager.java +++ b/core/java/android/security/FileIntegrityManager.java @@ -78,7 +78,7 @@ public final class FileIntegrityManager { * as a separate file and stored next to the targeting file in the filesystem. The public key of * the signer (normally the same app developer) can be put in the APK, and the app can use the * public key to verify the signature to the file's actual fs-verity digest (from {@link - * #getFsverityDigest}) before using the file. The exact format is not prescribed by the + * #getFsVerityDigest}) before using the file. The exact format is not prescribed by the * framework. App developers may choose to use common practices like JCA for the signing and * verification, or their own preferred approach. * @@ -87,7 +87,7 @@ public final class FileIntegrityManager { * @see <a href="https://www.kernel.org/doc/html/next/filesystems/fsverity.html">Kernel doc</a> */ @FlaggedApi(Flags.FLAG_FSVERITY_API) - public void setupFsverity(@NonNull File file) throws IOException { + public void setupFsVerity(@NonNull File file) throws IOException { if (!file.isAbsolute()) { throw new IllegalArgumentException("Expect an absolute path"); } @@ -104,7 +104,7 @@ public final class FileIntegrityManager { int errno = mService.setupFsverity(authToken, file.getPath(), mContext.getPackageName()); if (errno != 0) { - new ErrnoException("setupFsverity", errno).rethrowAsIOException(); + new ErrnoException("setupFsVerity", errno).rethrowAsIOException(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -120,7 +120,7 @@ public final class FileIntegrityManager { * @see <a href="https://www.kernel.org/doc/html/next/filesystems/fsverity.html">Kernel doc</a> */ @FlaggedApi(Flags.FLAG_FSVERITY_API) - public @Nullable byte[] getFsverityDigest(@NonNull File file) throws IOException { + public @Nullable byte[] getFsVerityDigest(@NonNull File file) throws IOException { return VerityUtils.getFsverityDigest(file.getPath()); } diff --git a/core/java/android/service/trust/OWNERS b/core/java/android/service/trust/OWNERS index 16eb19a58952..d3525250ebb6 100644 --- a/core/java/android/service/trust/OWNERS +++ b/core/java/android/service/trust/OWNERS @@ -1,3 +1,4 @@ # Bug component: 36824 jacobhobbie@google.com +dlm@google.com diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index c7e54537703b..637770c4fb21 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -1307,9 +1307,9 @@ public abstract class WallpaperService extends Service { visibleFrame.intersect(mInsetsState.getDisplayFrame()); WindowInsets windowInsets = mInsetsState.calculateInsets(visibleFrame, null /* ignoringVisibilityState */, config.isScreenRound(), - false /* alwaysConsumeSystemBars */, mLayout.softInputMode, - mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, mLayout.type, - config.windowConfiguration.getWindowingMode(), null /* idSideMap */); + mLayout.softInputMode, mLayout.flags, SYSTEM_UI_FLAG_VISIBLE, + mLayout.type, config.windowConfiguration.getActivityType(), + null /* idSideMap */); if (!fixedSize) { final Rect padding = mIWallpaperEngine.mDisplayPadding; diff --git a/core/java/android/text/flags/deprecate_fonts_xml.aconfig b/core/java/android/text/flags/deprecate_fonts_xml.aconfig new file mode 100644 index 000000000000..58dc210af581 --- /dev/null +++ b/core/java/android/text/flags/deprecate_fonts_xml.aconfig @@ -0,0 +1,8 @@ +package: "com.android.text.flags" + +flag { + name: "deprecate_fonts_xml" + namespace: "text" + description: "Feature flag for deprecating fonts.xml. By setting true for this feature flag, the new font configuration XML, /system/etc/font_fallback.xml is used. The new XML has a new syntax and flexibility of variable font declarations, but it is not compatible with the apps that reads fonts.xml. So, fonts.xml is maintained as a subset of the font_fallback.xml" + bug: "281769620" +} diff --git a/core/java/android/text/flags/phrase_strict_fallback.aconfig b/core/java/android/text/flags/phrase_strict_fallback.aconfig new file mode 100644 index 000000000000..c67a21bca0b4 --- /dev/null +++ b/core/java/android/text/flags/phrase_strict_fallback.aconfig @@ -0,0 +1,8 @@ +package: "com.android.text.flags" + +flag { + name: "phrase_strict_fallback" + namespace: "text" + description: "Feature flag for automatic fallback from phrase based line break to strict line break." + bug: "281970875" +} diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 85f5395f2657..5fe2aa1f5295 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -156,6 +156,13 @@ public class FeatureFlagUtils { public static final String SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS = "settings_biometrics2_fingerprint"; + /** + * Flag to enable/disable remote auth enrollment and settings + * @hide + */ + public static final String SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS = + "settings_remoteauth_enrollment"; + /** Flag to enable/disable entire page in Accessibility -> Hearing aids * @hide */ @@ -248,6 +255,8 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "true"); DEFAULT_FLAGS.put(SETTINGS_BIOMETRICS2_FINGERPRINT_SETTINGS, "false"); DEFAULT_FLAGS.put("settings_press_hold_nav_handle_to_search", "false"); + // TODO: b/298454866 Replace with Trunk Stable Feature Flag + DEFAULT_FLAGS.put(SETTINGS_REMOTEAUTH_ENROLLMENT_SETTINGS, "false"); } private static final Set<String> PERSISTENT_FLAGS; diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java index 23afb03569ce..a208d1f1a558 100644 --- a/core/java/android/view/HandwritingInitiator.java +++ b/core/java/android/view/HandwritingInitiator.java @@ -81,6 +81,8 @@ public class HandwritingInitiator { private int mConnectionCount = 0; private final InputMethodManager mImm; + private final Rect mTempRect = new Rect(); + private final RectF mTempRectF = new RectF(); private final Region mTempRegion = new Region(); @@ -401,8 +403,9 @@ public class HandwritingInitiator { final View cachedHoverTarget = getCachedHoverTarget(); if (cachedHoverTarget != null) { - final Rect handwritingArea = getViewHandwritingArea(cachedHoverTarget); - if (isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget, + final Rect handwritingArea = mTempRect; + if (getViewHandwritingArea(cachedHoverTarget, handwritingArea) + && isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget, /* isHover */ true) && shouldTriggerStylusHandwritingForView(cachedHoverTarget)) { return cachedHoverTarget; @@ -445,8 +448,9 @@ public class HandwritingInitiator { // directly return the connectedView. final View connectedView = getConnectedView(); if (connectedView != null) { - Rect handwritingArea = getViewHandwritingArea(connectedView); - if (isInHandwritingArea(handwritingArea, x, y, connectedView, isHover) + Rect handwritingArea = mTempRect; + if (getViewHandwritingArea(connectedView, handwritingArea) + && isInHandwritingArea(handwritingArea, x, y, connectedView, isHover) && shouldTriggerStylusHandwritingForView(connectedView)) { return connectedView; } @@ -528,28 +532,30 @@ public class HandwritingInitiator { /** * Return the handwriting area of the given view, represented in the window's coordinate. * If the view didn't set any handwriting area, it will return the view's boundary. - * It will return null if the view or its handwriting area is not visible. * - * The handwriting area is clipped to its visible part. + * <p> The handwriting area is clipped to its visible part. * Notice that the returned rectangle is the view's original handwriting area without the - * view's handwriting area extends. + * view's handwriting area extends. </p> + * + * @param view the {@link View} whose handwriting area we want to compute. + * @param rect the {@link Rect} to receive the result. + * + * @return true if the view's handwriting area is still visible, or false if it's clipped and + * fully invisible. This method only consider the clip by given view's parents, but not the case + * where a view is covered by its sibling view. */ - @Nullable - private static Rect getViewHandwritingArea(@NonNull View view) { + private static boolean getViewHandwritingArea(@NonNull View view, @NonNull Rect rect) { final ViewParent viewParent = view.getParent(); if (viewParent != null && view.isAttachedToWindow() && view.isAggregatedVisible()) { final Rect localHandwritingArea = view.getHandwritingArea(); - final Rect globalHandwritingArea = new Rect(); if (localHandwritingArea != null) { - globalHandwritingArea.set(localHandwritingArea); + rect.set(localHandwritingArea); } else { - globalHandwritingArea.set(0, 0, view.getWidth(), view.getHeight()); - } - if (viewParent.getChildVisibleRect(view, globalHandwritingArea, null)) { - return globalHandwritingArea; + rect.set(0, 0, view.getWidth(), view.getHeight()); } + return viewParent.getChildVisibleRect(view, rect, null); } - return null; + return false; } /** diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index fabfed39a913..1ec7c41e4395 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -16,7 +16,7 @@ package android.view; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.view.EventLogTags.IMF_IME_ANIM_CANCEL; import static android.view.EventLogTags.IMF_IME_ANIM_FINISH; import static android.view.EventLogTags.IMF_IME_ANIM_START; @@ -39,6 +39,7 @@ import static android.view.InsetsState.ISIDE_LEFT; import static android.view.InsetsState.ISIDE_RIGHT; import static android.view.InsetsState.ISIDE_TOP; import static android.view.WindowInsets.Type.ime; +import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY; import static android.view.inputmethod.ImeTracker.TOKEN_NONE; @@ -62,7 +63,6 @@ import android.view.InsetsState.InternalInsetsSide; import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation.Bounds; -import android.view.WindowManager.LayoutParams; import android.view.animation.Interpolator; import android.view.inputmethod.ImeTracker; @@ -396,10 +396,9 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro private Insets getInsetsFromState(InsetsState state, Rect frame, @Nullable @InternalInsetsSide SparseIntArray idSideMap) { return state.calculateInsets(frame, null /* ignoringVisibilityState */, - false /* isScreenRound */, false /* alwaysConsumeSystemBars */, - LayoutParams.SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode*/, + false /* isScreenRound */, SOFT_INPUT_ADJUST_RESIZE /* legacySoftInputMode */, 0 /* legacyWindowFlags */, 0 /* legacySystemUiFlags */, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, idSideMap).getInsets(mTypes); + ACTIVITY_TYPE_UNDEFINED, idSideMap).getInsets(mTypes); } /** Computes the insets relative to the given frame. */ diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 8ec7d6779392..fb24211e591a 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -652,7 +652,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private int mLastLegacySoftInputMode; private int mLastLegacyWindowFlags; private int mLastLegacySystemUiFlags; - private int mLastWindowingMode; + private int mLastActivityType; private boolean mStartingAnimation; private int mCaptionInsetsHeight = 0; private int mImeCaptionBarInsetsHeight = 0; @@ -800,10 +800,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } - WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/, - mLastInsets.isRound(), false /* alwaysConsumeSystemBars */, + WindowInsets insets = state.calculateInsets(mFrame, + mState /* ignoringVisibilityState */, mLastInsets.isRound(), mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags, - mWindowType, mLastWindowingMode, null /* idSideMap */); + mWindowType, mLastActivityType, null /* idSideMap */); mHost.dispatchWindowInsetsAnimationProgress(insets, Collections.unmodifiableList(runningAnimations)); if (DEBUG) { @@ -939,30 +939,29 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } /** - * @see InsetsState#calculateInsets(Rect, InsetsState, boolean, boolean, int, int, int, int, - * int, android.util.SparseIntArray) + * @see InsetsState#calculateInsets(Rect, InsetsState, boolean, int, int, int, int, int, + * android.util.SparseIntArray) */ @VisibleForTesting - public WindowInsets calculateInsets(boolean isScreenRound, boolean alwaysConsumeSystemBars, - int windowType, int windowingMode, int legacySoftInputMode, int legacyWindowFlags, - int legacySystemUiFlags) { + public WindowInsets calculateInsets(boolean isScreenRound, int windowType, int activityType, + int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags) { mWindowType = windowType; - mLastWindowingMode = windowingMode; + mLastActivityType = activityType; mLastLegacySoftInputMode = legacySoftInputMode; mLastLegacyWindowFlags = legacyWindowFlags; mLastLegacySystemUiFlags = legacySystemUiFlags; - mLastInsets = mState.calculateInsets(mFrame, null /* ignoringVisibilityState*/, - isScreenRound, alwaysConsumeSystemBars, legacySoftInputMode, legacyWindowFlags, - legacySystemUiFlags, windowType, windowingMode, null /* idSideMap */); + mLastInsets = mState.calculateInsets(mFrame, null /* ignoringVisibilityState */, + isScreenRound, legacySoftInputMode, legacyWindowFlags, + legacySystemUiFlags, windowType, activityType, null /* idSideMap */); return mLastInsets; } /** * @see InsetsState#calculateVisibleInsets(Rect, int, int, int, int) */ - public Insets calculateVisibleInsets(int windowType, int windowingMode, + public Insets calculateVisibleInsets(int windowType, int activityType, @SoftInputModeFlags int softInputMode, int windowFlags) { - return mState.calculateVisibleInsets(mFrame, windowType, windowingMode, softInputMode, + return mState.calculateVisibleInsets(mFrame, windowType, activityType, softInputMode, windowFlags); } diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index af24140086ed..59e0932ecd80 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -16,6 +16,7 @@ package android.view; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.view.InsetsSource.FLAG_FORCE_CONSUMING; import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER; import static android.view.InsetsStateProto.DISPLAY_CUTOUT; @@ -39,7 +40,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.WindowConfiguration; +import android.app.WindowConfiguration.ActivityType; import android.graphics.Insets; import android.graphics.Rect; import android.os.Parcel; @@ -136,9 +137,8 @@ public class InsetsState implements Parcelable { * @return The calculated insets. */ public WindowInsets calculateInsets(Rect frame, @Nullable InsetsState ignoringVisibilityState, - boolean isScreenRound, boolean alwaysConsumeSystemBars, - int legacySoftInputMode, int legacyWindowFlags, int legacySystemUiFlags, - int windowType, @WindowConfiguration.WindowingMode int windowingMode, + boolean isScreenRound, int legacySoftInputMode, int legacyWindowFlags, + int legacySystemUiFlags, int windowType, @ActivityType int activityType, @Nullable @InternalInsetsSide SparseIntArray idSideMap) { Insets[] typeInsetsMap = new Insets[Type.SIZE]; Insets[] typeMaxInsetsMap = new Insets[Type.SIZE]; @@ -185,9 +185,8 @@ public class InsetsState implements Parcelable { if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) { compatInsetsTypes &= ~statusBars(); } - if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) { - // Clear all types but forceConsumingTypes. - compatInsetsTypes &= forceConsumingTypes; + if (clearsCompatInsets(windowType, legacyWindowFlags, activityType, forceConsumingTypes)) { + compatInsetsTypes = 0; } return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound, @@ -295,26 +294,27 @@ public class InsetsState implements Parcelable { return insets; } - public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode, + public Insets calculateVisibleInsets(Rect frame, int windowType, @ActivityType int activityType, @SoftInputModeFlags int softInputMode, int windowFlags) { - final boolean clearsCompatInsets = clearsCompatInsets( - windowType, windowFlags, windowingMode); final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST; final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING ? systemBars() | ime() : systemBars(); + @InsetsType int forceConsumingTypes = 0; Insets insets = Insets.NONE; for (int i = mSources.size() - 1; i >= 0; i--) { final InsetsSource source = mSources.valueAt(i); if ((source.getType() & visibleInsetsTypes) == 0) { continue; } - if (clearsCompatInsets && !source.hasFlags(FLAG_FORCE_CONSUMING)) { - continue; + if (source.hasFlags(FLAG_FORCE_CONSUMING)) { + forceConsumingTypes |= source.getType(); } insets = Insets.max(source.calculateVisibleInsets(frame), insets); } - return insets; + return clearsCompatInsets(windowType, windowFlags, activityType, forceConsumingTypes) + ? Insets.NONE + : insets; } /** @@ -662,10 +662,15 @@ public class InsetsState implements Parcelable { mSources.put(source.getId(), source); } - public static boolean clearsCompatInsets(int windowType, int windowFlags, int windowingMode) { + public static boolean clearsCompatInsets(int windowType, int windowFlags, + @ActivityType int activityType, @InsetsType int forceConsumingTypes) { return (windowFlags & FLAG_LAYOUT_NO_LIMITS) != 0 + // For compatibility reasons, this excludes the wallpaper, the system error windows, + // and the app windows while any system bar is forcibly consumed. && windowType != TYPE_WALLPAPER && windowType != TYPE_SYSTEM_ERROR - && !WindowConfiguration.inMultiWindowMode(windowingMode); + // This ensures the app content won't be obscured by compat insets even if the app + // has FLAG_LAYOUT_NO_LIMITS. + && (forceConsumingTypes == 0 || activityType != ACTIVITY_TYPE_STANDARD); } public void dump(String prefix, PrintWriter pw) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 9a4cb7298ee6..30fd2cfa5f28 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -105,6 +105,8 @@ import android.os.RemoteCallback; import android.os.RemoteException; import android.os.SystemClock; import android.os.Trace; +import android.os.Vibrator; +import android.os.vibrator.Flags; import android.sysprop.DisplayProperties; import android.text.InputType; import android.text.TextUtils; @@ -5411,6 +5413,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private PointerIcon mMousePointerIcon; + /** Vibrator for haptic feedback. */ + private Vibrator mVibrator; + /** * @hide */ @@ -27758,8 +27763,24 @@ public class View implements Drawable.Callback, KeyEvent.Callback, && !isHapticFeedbackEnabled()) { return false; } - return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, - (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0); + + final boolean always = (flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0; + if (Flags.useVibratorHapticFeedback()) { + if (!mAttachInfo.canPerformHapticFeedback()) { + return false; + } + getSystemVibrator().performHapticFeedback( + feedbackConstant, always, "View#performHapticFeedback"); + return true; + } + return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant, always); + } + + private Vibrator getSystemVibrator() { + if (mVibrator != null) { + return mVibrator; + } + return mVibrator = mContext.getSystemService(Vibrator.class); } /** @@ -31239,6 +31260,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return events; } + private boolean canPerformHapticFeedback() { + return mSession != null + && (mDisplay.getFlags() & Display.FLAG_TOUCH_FEEDBACK_DISABLED) == 0; + } + @Nullable ScrollCaptureInternal getScrollCaptureInternal() { if (mScrollCaptureInternal != null) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index e0fda7e51c33..60d964e32f6f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2848,16 +2848,15 @@ public final class ViewRootImpl implements ViewParent, if (mLastWindowInsets == null || forceConstruct) { final Configuration config = getConfiguration(); mLastWindowInsets = mInsetsController.calculateInsets( - config.isScreenRound(), mAttachInfo.mAlwaysConsumeSystemBars, - mWindowAttributes.type, config.windowConfiguration.getWindowingMode(), - mWindowAttributes.softInputMode, mWindowAttributes.flags, - (mWindowAttributes.systemUiVisibility + config.isScreenRound(), mWindowAttributes.type, + config.windowConfiguration.getActivityType(), mWindowAttributes.softInputMode, + mWindowAttributes.flags, (mWindowAttributes.systemUiVisibility | mWindowAttributes.subtreeSystemUiVisibility)); mAttachInfo.mContentInsets.set(mLastWindowInsets.getSystemWindowInsets().toRect()); mAttachInfo.mStableInsets.set(mLastWindowInsets.getStableInsets().toRect()); mAttachInfo.mVisibleInsets.set(mInsetsController.calculateVisibleInsets( - mWindowAttributes.type, config.windowConfiguration.getWindowingMode(), + mWindowAttributes.type, config.windowConfiguration.getActivityType(), mWindowAttributes.softInputMode, mWindowAttributes.flags).toRect()); } return mLastWindowInsets; diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 62e37a4f50d2..b8385c6ecba9 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1318,8 +1318,8 @@ public interface WindowManager extends ViewManager { * that have the ignore orientation request display setting enabled by OEMs * (enables compatibility mode for fixed orientation on Android 12 (API * level 31) or higher; see - * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility"> - * Large screen app compatibility</a> + * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-compatibility-mode"> + * Large screen compatibility mode</a> * for more details). * * <p>To opt out of the user aspect ratio compatibility override, add this property @@ -1358,8 +1358,8 @@ public interface WindowManager extends ViewManager { * that have the ignore orientation request display setting enabled by OEMs * (enables compatibility mode for fixed orientation on Android 12 (API * level 31) or higher; see - * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility"> - * Large screen app compatibility</a> + * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-compatibility-mode"> + * Large screen compatibility mode</a> * for more details). * * <p>To opt out of the full-screen option of the user aspect ratio compatibility diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig new file mode 100644 index 000000000000..92d34089cb22 --- /dev/null +++ b/core/java/android/view/inputmethod/flags.aconfig @@ -0,0 +1,8 @@ +package: "android.view.inputmethod" + +flag { + name: "refactor_insets_controller" + namespace: "inputmethod" + description: "Feature flag for refactoring InsetsController and removing ImeInsetsSourceConsumer" + bug: "298172246" +}
\ No newline at end of file diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index f99f13843bd7..ddcfb40e00ce 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -2098,17 +2098,14 @@ public class Editor { final int selectionEnd = mTextView.getSelectionEnd(); final InputMethodState ims = mInputMethodState; - if (ims != null && ims.mBatchEditNesting == 0) { + if (ims != null && ims.mBatchEditNesting == 0 + && (ims.mContentChanged || ims.mSelectionModeChanged)) { InputMethodManager imm = getInputMethodManager(); - if (imm != null) { - if (imm.isActive(mTextView)) { - if (ims.mContentChanged || ims.mSelectionModeChanged) { - // We are in extract mode and the content has changed - // in some way... just report complete new text to the - // input method. - reportExtractedText(); - } - } + if (imm != null && imm.hasActiveInputConnection(mTextView)) { + // We are in extract mode and the content has changed + // in some way... just report complete new text to the + // input method. + reportExtractedText(); } } @@ -4830,7 +4827,7 @@ public class Editor { if (null == imm) { return; } - if (!imm.isActive(mTextView)) { + if (!imm.hasActiveInputConnection(mTextView)) { return; } // Skip if the IME has not requested the cursor/anchor position. diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java index c2700536f849..2747233a4bf1 100644 --- a/core/java/android/window/DisplayWindowPolicyController.java +++ b/core/java/android/window/DisplayWindowPolicyController.java @@ -17,8 +17,10 @@ package android.window; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.view.Display.INVALID_DISPLAY; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.WindowConfiguration; import android.content.ComponentName; @@ -107,18 +109,38 @@ public abstract class DisplayWindowPolicyController { } /** - * Returns {@code true} if the given activities can be displayed on this virtual display and - * the windowing mode is supported. + * Returns {@code true} if all of the given activities can be launched on this virtual display + * in the configuration defined by the rest of the arguments. + * + * @see #canContainActivity + */ + public boolean canContainActivities(@NonNull List<ActivityInfo> activities, + @WindowConfiguration.WindowingMode int windowingMode) { + for (int i = 0; i < activities.size(); i++) { + if (!canContainActivity(activities.get(i), windowingMode, + /*launchingFromDisplayId=*/ INVALID_DISPLAY, /*isNewTask=*/ false)) { + return false; + } + } + return true; + } + + /** + * Returns {@code true} if the given activity can be launched on this virtual display in the + * configuration defined by the rest of the arguments. If the given intent would be intercepted + * by the display owner then this means that the activity cannot be launched. */ - public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities, - @WindowConfiguration.WindowingMode int windowingMode); + public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, + @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, + int launchingFromDisplayId, boolean isNewTask); /** - * Returns {@code true} if the given new task can be launched on this virtual display. + * Returns {@code true} if the given activity can be launched on this virtual display in the + * configuration defined by the rest of the arguments. */ - public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, Intent intent, - @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, - boolean isNewTask); + protected abstract boolean canContainActivity(@NonNull ActivityInfo activityInfo, + @WindowConfiguration.WindowingMode int windowingMode, + int launchingFromDisplayId, boolean isNewTask); /** * Called when an Activity window is layouted with the new changes where contains the diff --git a/core/java/android/window/WindowMetricsController.java b/core/java/android/window/WindowMetricsController.java index 2858f0a1a725..e32c8e58bb21 100644 --- a/core/java/android/window/WindowMetricsController.java +++ b/core/java/android/window/WindowMetricsController.java @@ -16,7 +16,7 @@ package android.window; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.view.View.SYSTEM_UI_FLAG_VISIBLE; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; @@ -80,7 +80,7 @@ public final class WindowMetricsController { final Rect bounds; final float density; final boolean isScreenRound; - final int windowingMode; + final int activityType; synchronized (ResourcesManager.getInstance()) { final Configuration config = mContext.getResources().getConfiguration(); final WindowConfiguration winConfig = config.windowConfiguration; @@ -90,11 +90,11 @@ public final class WindowMetricsController { // as DisplayMetrics#density density = config.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; isScreenRound = config.isScreenRound(); - windowingMode = winConfig.getWindowingMode(); + activityType = winConfig.getActivityType(); } final IBinder token = Context.getToken(mContext); final Supplier<WindowInsets> insetsSupplier = () -> getWindowInsetsFromServerForDisplay( - mContext.getDisplayId(), token, bounds, isScreenRound, windowingMode); + mContext.getDisplayId(), token, bounds, isScreenRound, activityType); return new WindowMetrics(new Rect(bounds), insetsSupplier, density); } @@ -105,23 +105,22 @@ public final class WindowMetricsController { * @param token the token of Activity or WindowContext * @param bounds the window bounds to calculate insets for * @param isScreenRound if the display identified by displayId is round - * @param windowingMode the windowing mode of the window to calculate insets for + * @param activityType the activity type of the window to calculate insets for * @return WindowInsets calculated for the given window bounds, on the given display */ private static WindowInsets getWindowInsetsFromServerForDisplay(int displayId, IBinder token, - Rect bounds, boolean isScreenRound, int windowingMode) { + Rect bounds, boolean isScreenRound, int activityType) { try { final InsetsState insetsState = new InsetsState(); - final boolean alwaysConsumeSystemBars = WindowManagerGlobal.getWindowManagerService() - .getWindowInsets(displayId, token, insetsState); + WindowManagerGlobal.getWindowManagerService().getWindowInsets( + displayId, token, insetsState); final float overrideInvScale = CompatibilityInfo.getOverrideInvertedScale(); if (overrideInvScale != 1f) { insetsState.scale(overrideInvScale); } return insetsState.calculateInsets(bounds, null /* ignoringVisibilityState */, - isScreenRound, alwaysConsumeSystemBars, SOFT_INPUT_ADJUST_NOTHING, - 0 /* flags */, SYSTEM_UI_FLAG_VISIBLE, - WindowManager.LayoutParams.INVALID_WINDOW_TYPE, windowingMode, + isScreenRound, SOFT_INPUT_ADJUST_NOTHING, 0 /* flags */, SYSTEM_UI_FLAG_VISIBLE, + WindowManager.LayoutParams.INVALID_WINDOW_TYPE, activityType, null /* idSideMap */); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -157,7 +156,7 @@ public final class WindowMetricsController { currentDisplayInfo.displayId, null /* token */, new Rect(0, 0, currentDisplayInfo.getNaturalWidth(), currentDisplayInfo.getNaturalHeight()), isScreenRound, - WINDOWING_MODE_FULLSCREEN); + ACTIVITY_TYPE_UNDEFINED); // Set the hardware-provided insets. windowInsets = new WindowInsets.Builder(windowInsets).setRoundedCorners( currentDisplayInfo.roundedCorners) diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig index 560e41b1aa33..b8d251fc5cc5 100644 --- a/core/java/android/window/flags/windowing_sdk.aconfig +++ b/core/java/android/window/flags/windowing_sdk.aconfig @@ -8,3 +8,10 @@ flag { description: "Whether the feature to sync different window-related config updates is enabled" bug: "260873529" } + +flag { + namespace: "windowing_sdk" + name: "activity_embedding_overlay_presentation_flag" + description: "Whether the overlay presentation feature is enabled" + bug: "243518738" +} diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 048912c0b2e2..2909b6a488b8 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -128,11 +128,6 @@ public final class SystemUiDeviceConfigFlags { // Flag related to Privacy Indicators /** - * Whether to show the complete ongoing app ops chip. - */ - public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_2_enabled"; - - /** * Whether to show app ops chip for just microphone + camera. */ public static final String PROPERTY_MIC_CAMERA_ENABLED = "camera_mic_icons_enabled"; diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index bb868018bc95..86ca077d77d9 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -1113,15 +1113,14 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind if (insets != null) { mLastForceConsumingTypes = insets.getForceConsumingTypes(); - @InsetsType int compatInsetsTypes = + final boolean clearsCompatInsets = clearsCompatInsets(attrs.type, attrs.flags, + getResources().getConfiguration().windowConfiguration.getActivityType(), + mLastForceConsumingTypes); + final @InsetsType int compatInsetsTypes = WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout(); - if (clearsCompatInsets(attrs.type, attrs.flags, - getResources().getConfiguration().windowConfiguration.getWindowingMode())) { - compatInsetsTypes &= mLastForceConsumingTypes; - } final Insets stableBarInsets = insets.getInsetsIgnoringVisibility( WindowInsets.Type.systemBars()); - final Insets systemInsets = compatInsetsTypes == 0 + final Insets systemInsets = clearsCompatInsets ? Insets.NONE : Insets.min(insets.getInsets(compatInsetsTypes), stableBarInsets); mLastTopInset = systemInsets.top; diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java index aa2318d219f8..483a184a7ba2 100644 --- a/core/java/com/android/internal/policy/TransitionAnimation.java +++ b/core/java/com/android/internal/policy/TransitionAnimation.java @@ -1303,10 +1303,9 @@ public class TransitionAnimation { ScreenCapture.ScreenshotHardwareBuffer buffer) { t.setBuffer(layer, buffer.getHardwareBuffer()); t.setDataSpace(layer, buffer.getColorSpace().getDataSpace()); - // Avoid showing dimming effect for HDR content when running animation. - if (buffer.containsHdrLayers()) { - t.setDimmingEnabled(layer, false); - } + // Avoid showing dimming effect for HDR content when running animations. + // TODO(b/298219334): Only do this if we know we already dimmed in the screenshot + t.setDimmingEnabled(layer, false); } /** Returns whether the hardware buffer passed in is marked as protected. */ diff --git a/core/java/com/android/internal/security/TEST_MAPPING b/core/java/com/android/internal/security/TEST_MAPPING index 2d598dc57613..0af3b03edefc 100644 --- a/core/java/com/android/internal/security/TEST_MAPPING +++ b/core/java/com/android/internal/security/TEST_MAPPING @@ -12,10 +12,6 @@ ] }, { - "name": "ApkVerityTest", - "file_patterns": ["VerityUtils\\.java"] - }, - { "name": "UpdatableSystemFontTest", "file_patterns": ["VerityUtils\\.java"] }, @@ -23,5 +19,11 @@ "name": "CtsApkVerityInstallHostTestCases", "file_patterns": ["VerityUtils\\.java"] } + ], + "postsubmit": [ + { + "name": "FsVerityTest", + "file_patterns": ["VerityUtils\\.java"] + } ] } diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index ccae67f3e953..6440cc3952f8 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2071,10 +2071,67 @@ jobject convertAudioMixerAttributesFromNative(JNIEnv *env, mixerBehavior); } -static jint convertAudioMixToNative(JNIEnv *env, - AudioMix *nAudioMix, - const jobject jAudioMix) -{ +static jint convertAudioMixingRuleToNative(JNIEnv *env, const jobject audioMixingRule, + std::vector<AudioMixMatchCriterion> *nCriteria) { + jobject jRuleCriteria = env->GetObjectField(audioMixingRule, gAudioMixingRuleFields.mCriteria); + + jobjectArray jCriteria = static_cast<jobjectArray>( + env->CallObjectMethod(jRuleCriteria, gArrayListMethods.toArray)); + env->DeleteLocalRef(jRuleCriteria); + + jint numCriteria = env->GetArrayLength(jCriteria); + if (numCriteria > MAX_CRITERIA_PER_MIX) { + numCriteria = MAX_CRITERIA_PER_MIX; + } + + nCriteria->resize(numCriteria); + for (jint i = 0; i < numCriteria; i++) { + AudioMixMatchCriterion &nCriterion = (*nCriteria)[i]; + + jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); + + nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule); + + const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK; + switch (match_rule) { + case RULE_MATCH_UID: + nCriterion.mValue.mUid = + env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); + break; + case RULE_MATCH_USERID: + nCriterion.mValue.mUserId = + env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); + break; + case RULE_MATCH_AUDIO_SESSION_ID: { + jint jAudioSessionId = + env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); + nCriterion.mValue.mAudioSessionId = static_cast<audio_session_t>(jAudioSessionId); + } break; + case RULE_MATCH_ATTRIBUTE_USAGE: + case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: { + jobject jAttributes = + env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr); + + auto paa = JNIAudioAttributeHelper::makeUnique(); + jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get()); + if (jStatus != AUDIO_JAVA_SUCCESS) { + return jStatus; + } + if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) { + nCriterion.mValue.mUsage = paa->usage; + } else { + nCriterion.mValue.mSource = paa->source; + } + env->DeleteLocalRef(jAttributes); + } break; + } + env->DeleteLocalRef(jCriterion); + } + env->DeleteLocalRef(jCriteria); + return AUDIO_JAVA_SUCCESS; +} + +static jint convertAudioMixToNative(JNIEnv *env, AudioMix *nAudioMix, const jobject jAudioMix) { nAudioMix->mMixType = env->GetIntField(jAudioMix, gAudioMixFields.mMixType); nAudioMix->mRouteFlags = env->GetIntField(jAudioMix, gAudioMixFields.mRouteFlags); nAudioMix->mDeviceType = @@ -2094,69 +2151,16 @@ static jint convertAudioMixToNative(JNIEnv *env, env->DeleteLocalRef(jFormat); jobject jRule = env->GetObjectField(jAudioMix, gAudioMixFields.mRule); - jobject jRuleCriteria = env->GetObjectField(jRule, gAudioMixingRuleFields.mCriteria); nAudioMix->mAllowPrivilegedMediaPlaybackCapture = env->GetBooleanField(jRule, gAudioMixingRuleFields.mAllowPrivilegedPlaybackCapture); nAudioMix->mVoiceCommunicationCaptureAllowed = env->GetBooleanField(jRule, gAudioMixingRuleFields.mVoiceCommunicationCaptureAllowed); - env->DeleteLocalRef(jRule); - jobjectArray jCriteria = static_cast<jobjectArray>( - env->CallObjectMethod(jRuleCriteria, gArrayListMethods.toArray)); - env->DeleteLocalRef(jRuleCriteria); - - jint numCriteria = env->GetArrayLength(jCriteria); - if (numCriteria > MAX_CRITERIA_PER_MIX) { - numCriteria = MAX_CRITERIA_PER_MIX; - } - for (jint i = 0; i < numCriteria; i++) { - AudioMixMatchCriterion nCriterion; + jint status = convertAudioMixingRuleToNative(env, jRule, &(nAudioMix->mCriteria)); - jobject jCriterion = env->GetObjectArrayElement(jCriteria, i); - - nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule); - - const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK; - switch (match_rule) { - case RULE_MATCH_UID: - nCriterion.mValue.mUid = env->GetIntField(jCriterion, - gAudioMixMatchCriterionFields.mIntProp); - break; - case RULE_MATCH_USERID: - nCriterion.mValue.mUserId = - env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); - break; - case RULE_MATCH_AUDIO_SESSION_ID: { - jint jAudioSessionId = - env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mIntProp); - nCriterion.mValue.mAudioSessionId = static_cast<audio_session_t>(jAudioSessionId); - } break; - case RULE_MATCH_ATTRIBUTE_USAGE: - case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: { - jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr); - - auto paa = JNIAudioAttributeHelper::makeUnique(); - jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, jAttributes, paa.get()); - if (jStatus != AUDIO_JAVA_SUCCESS) { - return jStatus; - } - if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) { - nCriterion.mValue.mUsage = paa->usage; - } else { - nCriterion.mValue.mSource = paa->source; - } - env->DeleteLocalRef(jAttributes); - } - break; - } - - nAudioMix->mCriteria.push_back(nCriterion); - env->DeleteLocalRef(jCriterion); - } - - env->DeleteLocalRef(jCriteria); + env->DeleteLocalRef(jRule); - return AUDIO_JAVA_SUCCESS; + return status; } static jint @@ -2200,6 +2204,45 @@ android_media_AudioSystem_registerPolicyMixes(JNIEnv *env, jobject clazz, return nativeToJavaStatus(status); } +static jint android_media_AudioSystem_updatePolicyMixes(JNIEnv *env, jobject clazz, + jobjectArray mixes, + jobjectArray updatedMixingRules) { + if (mixes == nullptr || updatedMixingRules == nullptr) { + return AUDIO_JAVA_BAD_VALUE; + } + + jsize updatesCount = env->GetArrayLength(mixes); + if (updatesCount == 0 || updatesCount != env->GetArrayLength(updatedMixingRules)) { + return AUDIO_JAVA_BAD_VALUE; + } + + std::vector<std::pair<AudioMix, std::vector<AudioMixMatchCriterion>>> updates(updatesCount); + for (int i = 0; i < updatesCount; i++) { + jobject jAudioMix = env->GetObjectArrayElement(mixes, i); + jobject jAudioMixingRule = env->GetObjectArrayElement(updatedMixingRules, i); + if (!env->IsInstanceOf(jAudioMix, gAudioMixClass) || + !env->IsInstanceOf(jAudioMixingRule, gAudioMixingRuleClass)) { + return AUDIO_JAVA_BAD_VALUE; + } + + jint ret; + if ((ret = convertAudioMixToNative(env, &updates[i].first, jAudioMix)) != + AUDIO_JAVA_SUCCESS) { + return ret; + } + if ((ret = convertAudioMixingRuleToNative(env, jAudioMixingRule, &updates[i].second)) != + AUDIO_JAVA_SUCCESS) { + return ret; + } + } + + ALOGV("AudioSystem::updatePolicyMixes numMixes %d", updatesCount); + int status = AudioSystem::updatePolicyMixes(updates); + ALOGV("AudioSystem::updatePolicyMixes returned %d", status); + + return nativeToJavaStatus(status); +} + static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz, jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) { AudioDeviceTypeAddrVector deviceVector; @@ -3158,6 +3201,10 @@ static const JNINativeMethod gMethods[] = MAKE_AUDIO_SYSTEM_METHOD(getAudioHwSyncForSession), MAKE_JNI_NATIVE_METHOD("registerPolicyMixes", "(Ljava/util/ArrayList;Z)I", android_media_AudioSystem_registerPolicyMixes), + MAKE_JNI_NATIVE_METHOD("updatePolicyMixes", + "([Landroid/media/audiopolicy/AudioMix;[Landroid/media/audiopolicy/" + "AudioMixingRule;)I", + android_media_AudioSystem_updatePolicyMixes), MAKE_JNI_NATIVE_METHOD("setUidDeviceAffinities", "(I[I[Ljava/lang/String;)I", android_media_AudioSystem_setUidDeviceAffinities), MAKE_AUDIO_SYSTEM_METHOD(removeUidDeviceAffinities), diff --git a/core/res/OWNERS b/core/res/OWNERS index b46902e3a8e9..0df7c2047bc1 100644 --- a/core/res/OWNERS +++ b/core/res/OWNERS @@ -52,3 +52,6 @@ per-file res/xml/power_profile_test.xml = file:/BATTERY_STATS_OWNERS # Telephony per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS + +# TV Input Framework +per-file res/values/config_tv_external_input_logging.xml = file:/services/core/java/com/android/server/tv/OWNERS diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml index d1a4935633cb..37d2fa0540f0 100644 --- a/core/res/res/layout/autofill_fill_dialog.xml +++ b/core/res/res/layout/autofill_fill_dialog.xml @@ -85,14 +85,18 @@ android:layout_marginStart="24dp" android:layout_marginEnd="24dp" android:theme="@style/Theme.DeviceDefault.AutofillHalfScreenDialogButton" - android:orientation="horizontal"> + android:orientation="horizontal" + android:gravity="center_vertical"> <Button android:id="@+id/autofill_dialog_no" android:layout_width="wrap_content" - android:layout_height="36dp" - android:layout_marginTop="6dp" - android:layout_marginBottom="6dp" + android:layout_height="40dp" + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:paddingTop="0dp" + android:paddingBottom="0dp" + android:minWidth="0dp" style="?android:attr/borderlessButtonStyle" android:text="@string/autofill_save_no"> </Button> @@ -107,9 +111,8 @@ <Button android:id="@+id/autofill_dialog_yes" android:layout_width="wrap_content" - android:layout_height="36dp" - android:layout_marginTop="6dp" - android:layout_marginBottom="6dp" + android:layout_height="40dp" + android:minWidth="0dp" style="@style/AutofillHalfSheetTonalButton" android:text="@string/autofill_save_yes" android:visibility="gone" > diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml index 85529d6a4b3b..bed19a87eb16 100644 --- a/core/res/res/layout/autofill_save.xml +++ b/core/res/res/layout/autofill_save.xml @@ -72,14 +72,18 @@ android:layout_marginTop="32dp" android:layout_marginBottom="18dp" android:theme="@style/Theme.DeviceDefault.AutofillHalfScreenDialogButton" - android:orientation="horizontal"> + android:orientation="horizontal" + android:gravity="center_vertical"> <Button android:id="@+id/autofill_save_no" android:layout_width="wrap_content" - android:layout_height="36dp" - android:layout_marginTop="6dp" - android:layout_marginBottom="6dp" + android:layout_height="40dp" + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:paddingTop="0dp" + android:paddingBottom="0dp" + android:minWidth="0dp" style="?android:attr/borderlessButtonStyle" android:text="@string/autofill_save_no"> </Button> @@ -94,9 +98,8 @@ <Button android:id="@+id/autofill_save_yes" android:layout_width="wrap_content" - android:layout_height="36dp" - android:layout_marginTop="6dp" - android:layout_marginBottom="6dp" + android:layout_height="40dp" + android:minWidth="0dp" style="@style/AutofillHalfSheetTonalButton" android:text="@string/autofill_save_yes"> </Button> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 46fb80c77841..b1caec253949 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloon <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privaat <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vra PIN voordat jy ontspeld"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vra ontsluitpatroon voordat jy ontspeld"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vra wagwoord voordat jy ontspeld"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Dateer op in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Dateer <xliff:g id="TYPE">%1$s</xliff:g> op in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Dateer <xliff:g id="TYPE_0">%1$s</xliff:g> en <xliff:g id="TYPE_1">%2$s</xliff:g> op in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Dateer hierdie items op in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> en <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Stoor"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nee, dankie"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Nie nou nie"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 40246beffbf2..8109e9ab4cae 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ኛ ሥራ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ኛ ሥራ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ን አባዛ"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ከመንቀል በፊት ፒን ጠይቅ"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ስርዓተ-ጥለት ጠይቅ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"በ"<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ውስጥ ይዘመን?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> በ"<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ውስጥ ይዘመን?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> እና <xliff:g id="TYPE_1">%2$s</xliff:g> በ"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ውስጥ ይዘመኑ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"እነዚህ ንጥሎች በ"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ውስጥ ይዘመኑ፦ <xliff:g id="TYPE_0">%1$s</xliff:g>፣ <xliff:g id="TYPE_1">%2$s</xliff:g> እና <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"አስቀምጥ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"አይ፣ አመሰግናለሁ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"አሁን አይደለም"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 0286d42611dc..ff1ecdca11da 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1871,6 +1871,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"العمل الثاني <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"العمل الثالث <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"نسخة طبق الأصل عن \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"ملف شخصي خاص على <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"طلب إدخال رقم التعريف الشخصي قبل إزالة التثبيت"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال النقش الخاص بإلغاء القفل قبل إزالة التثبيت"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string> @@ -2035,8 +2036,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"هل تريد التحديث في "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"؟"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"هل تريد تحديث <xliff:g id="TYPE">%1$s</xliff:g> في "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"؟"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"هل تريد تحديث <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> في "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"؟"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"هل تريد تعديل هذه العناصر في "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g> و<xliff:g id="TYPE_1">%2$s</xliff:g> و<xliff:g id="TYPE_2">%3$s</xliff:g>؟"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"حفظ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"لا، شكرًا"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ليس الآن"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index a1679b3bdc38..f2aee4063cc9 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"২য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"৩য় কার্য <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"ক্ল’ন <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন কৰাৰ পূৰ্বে পিন দিবলৈ কওক"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"ত আপডে’ট কৰিবনে?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"ত <xliff:g id="TYPE">%1$s</xliff:g> আপডে’ট কৰিবনে?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"ত <xliff:g id="TYPE_0">%1$s</xliff:g> আৰু <xliff:g id="TYPE_1">%2$s</xliff:g> আপডে’ট কৰিবনে?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"এই তথ্যবোৰ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> আৰু <xliff:g id="TYPE_2">%3$s</xliff:g>ত আপডে’ট কৰিবনে?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ছেভ কৰক"</string> <string name="autofill_save_no" msgid="9212826374207023544">"নালাগে, ধন্যবাদ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"এতিয়া নহয়"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index 49a599e5dd09..0004ba87d9fd 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ci İş <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-cü İş <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kopyalayın: <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Şəxsi <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ayırmadan öncə PIN istənilsin"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Qrafik açar istənilsin"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ayırmadan öncə parol istənilsin"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ünvanında yenilənsin?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ünvanında yenilənsin?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> və <xliff:g id="TYPE_1">%2$s</xliff:g> "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ünvanında yenilənsin?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> və <xliff:g id="TYPE_2">%3$s</xliff:g> bölmələrində bu elementlər yenilənsin?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Yadda saxlayın"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Xeyr, çox sağ olun"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"İndi yox"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 97483a4df1ae..592c3440c7e1 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -494,7 +494,7 @@ <string name="permdesc_sim_communication" msgid="4179799296415957960">"Omogućava aplikaciji da šalje komande SIM kartici. To je veoma opasno."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string> - <string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i video snimaka"</string> + <string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i videa"</string> <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string> <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string> <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string> @@ -745,8 +745,8 @@ <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Omogućava aplikaciji da čita video fajlove iz deljenog memorijskog prostora."</string> <string name="permlab_readMediaImages" msgid="4057590631020986789">"čitanje fajlova slika iz deljenog memorijskog prostora"</string> <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Omogućava aplikaciji da čita fajlove slika iz deljenog memorijskog prostora."</string> - <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"čitanje fajlova slika i video snimaka koje korisnik bira iz deljenog memorijskog prostora"</string> - <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Omogućava aplikaciji da čita fajlove slika i video snimaka koje izaberete iz deljenog memorijskog prostora."</string> + <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"čitanje fajlova slika i videa koje korisnik bira iz deljenog memorijskog prostora"</string> + <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Omogućava aplikaciji da čita fajlove slika i videa koje izaberete iz deljenog memorijskog prostora."</string> <string name="permlab_sdcardWrite" msgid="4863021819671416668">"menjanje ili brisanje sadržaja deljenog memorijskog prostora"</string> <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Dozvoljava aplikaciji da upisuje sadržaj deljenog memorijskog prostora."</string> <string name="permlab_use_sip" msgid="8250774565189337477">"upućivanje/prijem SIP poziva"</string> @@ -1172,7 +1172,7 @@ <string name="app_running_notification_text" msgid="5120815883400228566">"Dodirnite za više informacija ili zaustavljanje aplikacije."</string> <string name="ok" msgid="2646370155170753815">"Potvrdi"</string> <string name="cancel" msgid="6908697720451760115">"Otkaži"</string> - <string name="yes" msgid="9069828999585032361">"Potvrdi"</string> + <string name="yes" msgid="9069828999585032361">"U redu"</string> <string name="no" msgid="5122037903299899715">"Otkaži"</string> <string name="dialog_alert_title" msgid="651856561974090712">"Pažnja"</string> <string name="loading" msgid="3138021523725055037">"Učitava se…"</string> @@ -1417,7 +1417,7 @@ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Dodirnite da biste podesili"</string> <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Izaberite da biste podesili"</string> <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Možda morate da reformatirate uređaj. Dodirnite da biste izbacili."</string> - <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Za čuvanje slika, video snimaka, muzike i drugog sadržaja"</string> + <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Za čuvanje slika, videa, muzike i drugog sadržaja"</string> <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Pregledajte medijske fajlove"</string> <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Problem sa: <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> ne radi"</string> @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni imejl <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniraj <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privatni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN pre otkačinjanja"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Želite li da ažurirate u usluzi "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Želite li da ažurirate stavku <xliff:g id="TYPE">%1$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Želite li da ažurirate stavke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u usluzi "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Želite li da ažurirate ove stavke u usluzi "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index cd87b5291fbb..4cd8aa589d65 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -671,14 +671,10 @@ </string-array> <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Нешта пайшло не так. Паўтарыце спробу."</string> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок адбіткаў пальцаў"</string> - <!-- no translation found for device_unlock_notification_name (2632928999862915709) --> - <skip /> - <!-- no translation found for alternative_unlock_setup_notification_title (6241508547901933544) --> - <skip /> - <!-- no translation found for alternative_face_setup_notification_content (3384959224091897331) --> - <skip /> - <!-- no translation found for alternative_fp_setup_notification_content (7454096947415721639) --> - <skip /> + <string name="device_unlock_notification_name" msgid="2632928999862915709">"Разблакіроўка прылады"</string> + <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Паспрабуйце іншы спосаб разблакіроўкі"</string> + <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Выкарыстоўвайце распазнаванне твару, калі прылада не распазнае ваш адбітак пальца. Гэта функцыя можа прыдацца, напрыклад, калі ў вас мокрыя пальцы."</string> + <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Выкарыстоўвайце разблакіроўку адбіткам пальца, калі прылада не распазнае ваш твар. Гэта функцыя можа прыдацца, напрыклад, ва ўмовах недастатковай асветленасці."</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Распазнаванне твару"</string> <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Праблема з распазнаваннем твару"</string> <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Націсніце, каб выдаліць мадэль твару, пасля дадайце твар яшчэ раз"</string> @@ -1873,6 +1869,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Другая праца <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трэцяя праца <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Кланіраваць \"<xliff:g id="LABEL">%1$s</xliff:g>\""</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запытваць PIN-код перад адмацаваннем"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string> @@ -2037,8 +2035,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Абнавіць у сэрвісе "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Абнавіць даныя \"<xliff:g id="TYPE">%1$s</xliff:g>\" у сэрвісе "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Абнавіць даныя \"<xliff:g id="TYPE_0">%1$s</xliff:g>\" і \"<xliff:g id="TYPE_1">%2$s</xliff:g>\" у сэрвісе "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Абнавіць наступныя даныя ў сэрвісе "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Захаваць"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Не, дзякуй"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не зараз"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 7810776bed92..97345fcf4b3d 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Втори служебен профил (<xliff:g id="LABEL">%1$s</xliff:g>)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трети служебен профил (<xliff:g id="LABEL">%1$s</xliff:g>)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Копие на <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Частен <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запитване за ПИН код преди освобождаване"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитване за фигура за отключване преди освобождаване"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитване за парола преди освобождаване"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Искате ли да актуализирате в(ъв) "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Искате ли да актуализирате <xliff:g id="TYPE">%1$s</xliff:g> в(ъв) "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Искате ли да актуализирате <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> в(ъв) "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Искате ли да актуализирате тези елементи в(ъв) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Запазване"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Не, благодаря"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сега"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 02bfaae2cfe9..1d1e29c9d517 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"দ্বিতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"তৃতীয় কার্যক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ক্লোন"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"আনপিন করার আগে পিন চান"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"-এ আপডেট করতে চান?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"-এ <xliff:g id="TYPE">%1$s</xliff:g> আপডেট করতে চান?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"-এ <xliff:g id="TYPE_0">%1$s</xliff:g> এবং <xliff:g id="TYPE_1">%2$s</xliff:g> আপডেট করতে চান?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"এইসব আইটেম "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-এ আপডেট করতে চান: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ও <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"সেভ করুন"</string> <string name="autofill_save_no" msgid="9212826374207023544">"না থাক"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"এখনই নয়"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 00aa3073a761..3fd0637d27f9 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniranje aplikacije <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> – privatno"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN prije nego se otkači"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje prije poništavanja kačenja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku prije nego se otkači"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Ažurirati u "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Ažurirati <xliff:g id="TYPE">%1$s</xliff:g> u "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Ažurirati <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Ažurirati ove stavke u oznaci "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Sačuvaj"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sada"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 42e631b78805..5ec91f5ebce8 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1868,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2n <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3r <xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sol·licita el PIN per deixar de fixar"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string> @@ -2032,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vols actualitzar-ho a "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vols actualitzar <xliff:g id="TYPE">%1$s</xliff:g> a "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vols actualitzar <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> a "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vols actualitzar aquests elements a "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Desa"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, gràcies"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ara no"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 772ef5334f82..89d25015d4db 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1869,6 +1869,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Soukromá aplikace <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Před uvolněním požádat o PIN"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string> @@ -2033,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Aktualizovat ve službě "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Aktualizovat údaj <xliff:g id="TYPE">%1$s</xliff:g> ve službě "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Aktualizovat údaje <xliff:g id="TYPE_0">%1$s</xliff:g> a <xliff:g id="TYPE_1">%2$s</xliff:g> ve službě "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Aktualizovat tyto položky ve službě "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Uložit"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, děkuji"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Teď ne"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 697800b8e951..ca2206c9be1d 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -671,12 +671,12 @@ <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeraftryk"</string> <string name="device_unlock_notification_name" msgid="2632928999862915709">"Enhedsoplåsning"</string> <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Prøv en anden metode til oplåsning"</string> - <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Brug ansigtslås, hvis dit fingeraftryk ikke genkendes, f.eks. når du har våde fingre"</string> + <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Brug ansigtsoplåsning, hvis dit fingeraftryk ikke genkendes, f.eks. når du har våde fingre"</string> <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Brug oplåsning med fingeraftryk, hvis dit ansigt ikke genkendes, f.eks. når der ikke er nok lys"</string> - <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansigtslås"</string> - <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Der er et problem med Ansigtslås"</string> + <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Ansigtsoplåsning"</string> + <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Der er et problem med Ansigtsoplåsning"</string> <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tryk for at slette din ansigtsmodel, og tilføj derefter dit ansigt igen"</string> - <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Hvis du vil bruge ansigtslåsen, skal du aktivere "<b>"Kameraadgang"</b>" under Indstillinger > Privatliv"</string> + <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Hvis du vil bruge ansigtsoplåsning, skal du aktivere "<b>"Kameraadgang"</b>" under Indstillinger > Privatliv"</string> <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Oplåsning med fingeraftryk"</string> <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Fingeraftrykssensoren kan ikke bruges"</string> <string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Få den repareret."</string> @@ -710,19 +710,19 @@ <string-array name="face_acquired_vendor"> </string-array> <string name="face_error_hw_not_available" msgid="5085202213036026288">"Ansigt ikke verificeret. Hardware ikke tilgængelig."</string> - <string name="face_error_timeout" msgid="2598544068593889762">"Prøv ansigtslås igen"</string> + <string name="face_error_timeout" msgid="2598544068593889762">"Prøv ansigtsoplåsning igen"</string> <string name="face_error_no_space" msgid="5649264057026021723">"Der kan ikke gemmes nye ansigtsdata. Slet et gammelt først."</string> <string name="face_error_canceled" msgid="2164434737103802131">"Ansigtshandlingen blev annulleret."</string> - <string name="face_error_user_canceled" msgid="5766472033202928373">"Ansigtslås blev annulleret af brugeren"</string> + <string name="face_error_user_canceled" msgid="5766472033202928373">"Ansigtsoplåsning blev annulleret af brugeren"</string> <string name="face_error_lockout" msgid="7864408714994529437">"Du har prøvet for mange gange. Prøv igen senere."</string> - <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Du har brugt for mange forsøg. Ansigtslås er utilgængelig."</string> + <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Du har brugt for mange forsøg. Ansigtsoplåsning er utilgængelig."</string> <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Du har brugt for mange forsøg. Angiv skærmlåsen i stedet."</string> <string name="face_error_unable_to_process" msgid="5723292697366130070">"Ansigtet kan ikke genkendes. Prøv igen."</string> - <string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har ikke konfigureret ansigtslås."</string> - <string name="face_error_hw_not_present" msgid="7940978724978763011">"Ansigtslås understøttes ikke på denne enhed"</string> + <string name="face_error_not_enrolled" msgid="1134739108536328412">"Du har ikke konfigureret ansigtsoplåsning."</string> + <string name="face_error_hw_not_present" msgid="7940978724978763011">"Ansigtsoplåsning understøttes ikke på denne enhed"</string> <string name="face_error_security_update_required" msgid="5076017208528750161">"Sensoren er midlertidigt deaktiveret."</string> <string name="face_name_template" msgid="3877037340223318119">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string> - <string name="face_app_setting_name" msgid="5854024256907828015">"Brug ansigtslås"</string> + <string name="face_app_setting_name" msgid="5854024256907828015">"Brug ansigtsoplåsning"</string> <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Brug ansigts- eller skærmlås"</string> <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Brug dit ansigt for at fortsætte"</string> <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Brug din ansigts- eller skærmlås for at fortsætte"</string> @@ -975,7 +975,7 @@ <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Prøv igen"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Prøv igen"</string> <string name="lockscreen_storage_locked" msgid="634993789186443380">"Lås op for at se alle funktioner og data"</string> - <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Det maksimale antal forsøg på at bruge ansigtslås er overskredet"</string> + <string name="faceunlock_multiple_failures" msgid="681991538434031708">"Det maksimale antal forsøg på at bruge ansigtsoplåsning er overskredet"</string> <string name="lockscreen_missing_sim_message_short" msgid="1229301273156907613">"Intet SIM-kort"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="3986843848305639161">"Intet SIM-kort i tabletten."</string> <string name="lockscreen_missing_sim_message" product="tv" msgid="3903140876952198273">"Intet SIM-kort i din Android TV-enhed."</string> @@ -1045,7 +1045,7 @@ <string name="keyguard_accessibility_expand_lock_area" msgid="4215280881346033434">"Udvid oplåsningsområdet."</string> <string name="keyguard_accessibility_slide_unlock" msgid="2968195219692413046">"Lås op ved at stryge."</string> <string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Lås op med mønster."</string> - <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Ansigtslås."</string> + <string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Ansigtsoplåsning."</string> <string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Lås op med pinkode."</string> <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"Lås op ved hjælp af pinkoden til SIM-kortet."</string> <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"Lås op ved hjælp af PUK-koden til SIM-kortet."</string> @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> til arbejde"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon af <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Bed om pinkode inden frigørelse"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vil du opdatere i "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vil du opdatere <xliff:g id="TYPE">%1$s</xliff:g> i "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vil du opdatere <xliff:g id="TYPE_0">%1$s</xliff:g> og <xliff:g id="TYPE_1">%2$s</xliff:g> i "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vil du opdatere disse elementer i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Gem"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nej tak"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ikke nu"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index b5e38b9f6340..be511e8a7c32 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -669,14 +669,10 @@ </string-array> <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Ein Problem ist aufgetreten. Versuch es noch einmal."</string> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerabdruck-Symbol"</string> - <!-- no translation found for device_unlock_notification_name (2632928999862915709) --> - <skip /> - <!-- no translation found for alternative_unlock_setup_notification_title (6241508547901933544) --> - <skip /> - <!-- no translation found for alternative_face_setup_notification_content (3384959224091897331) --> - <skip /> - <!-- no translation found for alternative_fp_setup_notification_content (7454096947415721639) --> - <skip /> + <string name="device_unlock_notification_name" msgid="2632928999862915709">"Geräteentsperrung"</string> + <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Andere Entsperrungsart verwenden"</string> + <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Verwende die Entsperrung per Gesichtserkennung, wenn dein Fingerabdruck nicht erkannt wird, beispielsweise wenn deine Finger nass sind"</string> + <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Verwende die Entsperrung per Fingerabdruck, wenn dein Gesicht nicht erkannt wird, beispielsweise wenn es zu dunkel ist"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Entsperrung per Gesichtserkennung"</string> <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problem bei der Entsperrung per Gesichtserkennung"</string> <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Tippe, um dein Gesichtsmodell zu löschen, und füge es dann noch einmal hinzu"</string> @@ -1871,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vor dem Beenden nach PIN fragen"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string> @@ -2035,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"In "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" aktualisieren?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" aktualisieren?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> und <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" aktualisieren?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> und <xliff:g id="TYPE_2">%3$s</xliff:g> in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" aktualisieren?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Speichern"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nein danke"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Nicht jetzt"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index a0a44746251e..1d3471c0db95 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> εργασίας 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> εργασίας 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Κλώνος <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Ιδιωτικό <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Να γίνεται ερώτηση για το PIN, πριν από το ξεκαρφίτσωμα"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Ενημέρωση σε "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>";"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Ενημέρωση <xliff:g id="TYPE">%1$s</xliff:g> σε "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>";"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Ενημέρωση <xliff:g id="TYPE_0">%1$s</xliff:g> και <xliff:g id="TYPE_1">%2$s</xliff:g> σε "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>";"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Ενημέρωση αυτών των στοιχείων στο "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> και <xliff:g id="TYPE_2">%3$s</xliff:g>;"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Αποθήκευση"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Όχι, ευχαριστώ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Όχι τώρα"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index a931c58fec17..8c33f168f17d 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Private <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Update in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Update <xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Update <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 1d657c7c202e..6dc9ce4ce735 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Private <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Update in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Update <xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Update <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No thanks"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 275b1bcc717b..3daab6cc1cfa 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Private <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Update in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Update <xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Update <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 3504a53d6c11..67ebab14d297 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Private <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Update in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Update <xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Update <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, thanks"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 9a727491bc14..d8b5016449b1 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2nd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3rd Work <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Private <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Ask for PIN before unpinning"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ask for unlock pattern before unpinning"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ask for password before unpinning"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Update in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Update <xliff:g id="TYPE">%1$s</xliff:g> in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Update <xliff:g id="TYPE_0">%1$s</xliff:g> and <xliff:g id="TYPE_1">%2$s</xliff:g> in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Update these items in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, and <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No thanks"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Not now"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 8b651d138b67..e0aeb31e721d 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privado"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicitar PIN para quitar fijación"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicitar desbloqueo para quitar fijación"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para quitar fijación"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"¿Quieres actualizar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"¿Quieres actualizar <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"¿Quieres actualizar <xliff:g id="TYPE_0">%1$s</xliff:g> y <xliff:g id="TYPE_1">%2$s</xliff:g> en "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"¿Quieres actualizar estos elementos en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, gracias"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ahora no"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 9c678c578172..3bcc0f432a88 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1868,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clon de <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicitar PIN para desactivar"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string> @@ -2032,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"¿Actualizar en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"¿Actualizar <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"¿Actualizar <xliff:g id="TYPE_0">%1$s</xliff:g> y <xliff:g id="TYPE_1">%2$s</xliff:g> en "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"¿Actualizar estos elementos en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> y <xliff:g id="TYPE_2">%3$s</xliff:g>)?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, gracias"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ahora no"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index c17a17995733..d212946da95e 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. töö <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. töö <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Rakenduse <xliff:g id="LABEL">%1$s</xliff:g> kloon"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privaatne <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Enne vabastamist küsi PIN-koodi"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Kas värskendada üksust teenuses "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Kas värskendada üksust <xliff:g id="TYPE">%1$s</xliff:g> teenuses "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Kas värskendada üksusi <xliff:g id="TYPE_0">%1$s</xliff:g> ja <xliff:g id="TYPE_1">%2$s</xliff:g> teenuses "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Kas värskendada teenuses "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" neid üksusi: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Salvesta"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Tänan, ei"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Hiljem"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 7a6fa1d5699e..302acb04d085 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -669,14 +669,10 @@ </string-array> <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Arazo bat izan da. Saiatu berriro."</string> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string> - <!-- no translation found for device_unlock_notification_name (2632928999862915709) --> - <skip /> - <!-- no translation found for alternative_unlock_setup_notification_title (6241508547901933544) --> - <skip /> - <!-- no translation found for alternative_face_setup_notification_content (3384959224091897331) --> - <skip /> - <!-- no translation found for alternative_fp_setup_notification_content (7454096947415721639) --> - <skip /> + <string name="device_unlock_notification_name" msgid="2632928999862915709">"Gailua desblokeatzea"</string> + <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Probatu gailua desblokeatzeko beste modu bat"</string> + <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Erabili Aurpegi bidez desblokeatzea hatz-marka ezagutzen ez denean (adibidez, hatzak bustita dauzkazunean)"</string> + <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Erabili Hatz-marka bidez desblokeatzea aurpegia ezagutzen ez denean (adibidez, argi nahikorik ez dagoenean)"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Aurpegi bidez desblokeatzea"</string> <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Arazoak ditugu aurpegi bidez desblokeatzeko eginbidearekin"</string> <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Sakatu hau aurpegi-eredua ezabatzeko eta, gero, gehitu aurpegia berriro"</string> @@ -1871,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Laneko 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Laneko 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> aplikazioaren klona"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Eskatu PINa aingura kendu aurretik"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string> @@ -2035,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" zerbitzuan eguneratu nahi duzu?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" zerbitzuan eguneratu nahi duzu <xliff:g id="TYPE">%1$s</xliff:g>?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" zerbitzuan eguneratu nahi dituzu <xliff:g id="TYPE_0">%1$s</xliff:g> eta <xliff:g id="TYPE_1">%2$s</xliff:g>?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" zerbitzuan eguneratu nahi dituzu <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> eta <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Gorde"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ez, eskerrik asko"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Orain ez"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index c733bea6cfb5..7947b6ea6e8b 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1133,9 +1133,9 @@ <string name="duration_hours_relative_future" msgid="6670440478481140565">"{count,plural, =1{# ساعت}one{# ساعت}other{# ساعت}}"</string> <string name="duration_days_relative_future" msgid="8870658635774250746">"{count,plural, =1{# روز}one{# روز}other{# روز}}"</string> <string name="duration_years_relative_future" msgid="8855853883925918380">"{count,plural, =1{# سال}one{# سال}other{# سال}}"</string> - <string name="VideoView_error_title" msgid="5750686717225068016">"مشکل در ویدئو"</string> - <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"متأسفیم، این ویدئو برای پخش جریانی با این دستگاه معتبر نیست."</string> - <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"پخش این ویدئو ممکن نیست."</string> + <string name="VideoView_error_title" msgid="5750686717225068016">"مشکل در ویدیو"</string> + <string name="VideoView_error_text_invalid_progressive_playback" msgid="3782449246085134720">"متأسفیم، این ویدیو برای پخش جریانی با این دستگاه معتبر نیست."</string> + <string name="VideoView_error_text_unknown" msgid="7658683339707607138">"پخش این ویدیو ممکن نیست."</string> <string name="VideoView_error_button" msgid="5138809446603764272">"تأیید"</string> <string name="relative_time" msgid="8572030016028033243">"<xliff:g id="DATE">%1$s</xliff:g>، <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="noon" msgid="8365974533050605886">"ظهر"</string> @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"کار دوم <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"کار سوم <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"همسانه <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"درخواست کد پین قبل از برداشتن پین"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"درخواست الگوی بازگشایی قفل قبلاز برداشتن سنجاق"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"درخواست گذرواژه قبل از برداشتن سنجاق"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"در "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" بهروزرسانی شود؟"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> در "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" بهروزرسانی شود؟"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> و <xliff:g id="TYPE_1">%2$s</xliff:g> در "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" بهروزرسانی شود؟"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"این موارد در "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>، <xliff:g id="TYPE_1">%2$s</xliff:g>، و <xliff:g id="TYPE_2">%3$s</xliff:g> بهروزرسانی شود؟"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ذخیره"</string> <string name="autofill_save_no" msgid="9212826374207023544">"نه سپاسگزارم"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"حالا نه"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 5cf1c99db7e4..3b5c86e9f37d 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Toinen <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Kolmas <xliff:g id="LABEL">%1$s</xliff:g>, työ"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloonaa <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pyydä PIN ennen irrotusta"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Päivitetäänkö "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Päivitetäänkö <xliff:g id="TYPE">%1$s</xliff:g> ("<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>")?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Päivitetäänkö <xliff:g id="TYPE_0">%1$s</xliff:g> ja <xliff:g id="TYPE_1">%2$s</xliff:g> ("<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>")?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Päivitetäänkö nämä ("<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"): <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ja <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Tallenna"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ei kiitos"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ei nyt"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index fda118332241..782ccd0e45ce 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g> professionnel(le)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g> professionnel(le)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone de <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privé"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le NIP avant d\'annuler l\'épinglage"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant d\'annuler l\'épinglage"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant d\'annuler l\'épinglage"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Mettre à jour sous "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Mettre à jour <xliff:g id="TYPE">%1$s</xliff:g> sous "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Mettre à jour <xliff:g id="TYPE_0">%1$s</xliff:g> et <xliff:g id="TYPE_1">%2$s</xliff:g> sous "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Mettre à jour ces éléments sous "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" : <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Enregistrer"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Non, merci"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Pas maintenant"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 654a3f256ce6..b5ea2e2d8681 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1868,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g> professionnelle"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Cloner <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Demander le code avant de retirer l\'épingle"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string> @@ -2032,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Mettre à jour cet élément dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Mettre à jour <xliff:g id="TYPE">%1$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Mettre à jour <xliff:g id="TYPE_0">%1$s</xliff:g> et <xliff:g id="TYPE_1">%2$s</xliff:g> dans "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Mettre à jour ces éléments dans "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" : <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> et <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Enregistrer"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Non, merci"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Pas maintenant"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 51006b9d67f8..ea3f104d0d12 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3.º <xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonar <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de soltar a fixación"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Queres actualizar o contido en "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Queres actualizar <xliff:g id="TYPE">%1$s</xliff:g> en "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Queres actualizar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> en "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Queres actualizar estes datos (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>) en "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Gardar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Non, grazas"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora non"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index aa2a887cb2af..0a42b241e255 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3જું કાર્ય <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>ની ક્લોન"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"અનપિન કરતા પહેલાં પિન માટે પૂછો"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"માં અપડેટ કરીએ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>ને "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"માં અપડેટ કરીએ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> અને <xliff:g id="TYPE_1">%2$s</xliff:g>ને "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"માં અપડેટ કરીએ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"શું "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"માંની: આ <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> અને <xliff:g id="TYPE_2">%3$s</xliff:g> આઇટમને અપડેટ કરીએ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"સાચવો"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ના, આભાર"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"હમણાં નહીં"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index a81ada661d28..8a383a1bd5e2 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"दूसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"तीसरा काम <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> का क्लोन"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करने से पहले पिन के लिए पूछें"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"क्या आप "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" में अपडेट करना चाहते हैं?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"क्या आप "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" में <xliff:g id="TYPE">%1$s</xliff:g> अपडेट करना चाहते हैं?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"क्या आप "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" में <xliff:g id="TYPE_0">%1$s</xliff:g> और <xliff:g id="TYPE_1">%2$s</xliff:g> अपडेट करना चाहते हैं?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"क्या आपको "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" में इन आइटम को अपडेट करना है: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, और <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"सेव करें"</string> <string name="autofill_save_no" msgid="9212826374207023544">"नहीं, धन्यवाद"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"अभी नहीं"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index fefddbce9abe..d7f5b4ac1b00 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> za posao"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> za posao"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloniraj <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privatno <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Traži PIN radi otkvačivanja"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje radi otkvačivanja"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži zaporku radi otkvačivanja"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Želite li ažurirati u oznaku "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Želite li ažurirati podatke <xliff:g id="TYPE">%1$s</xliff:g> u oznaci "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Želite li ažurirati podatke <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> u oznaci "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Želite li ažurirati ove stavke u oznaci "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Spremi"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne sad"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 8c8b38fd76c4..57b81a0b4ac6 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> klónozása"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privát <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-kód kérése a kitűzés feloldásához"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Feloldási minta kérése a rögzítés feloldásához"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Jelszó kérése a rögzítés feloldásához"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Frissíti a(z) "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" szolgáltatásban?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Frissíti a(z) "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" szolgáltatásban a következőt: <xliff:g id="TYPE">%1$s</xliff:g>?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Frissíti a(z) "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" szolgáltatásban a következőket: <xliff:g id="TYPE_0">%1$s</xliff:g> és <xliff:g id="TYPE_1">%2$s</xliff:g>?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Frissíti a(z) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" szolgáltatásban a következőket: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> és <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Mentés"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nem, köszönöm"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne most"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index e240c31446c8..59827cb558b8 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-րդ աշխատանք <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>-ի կլոն"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Հարցնել PIN կոդը"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Հարցնել ապակողպող նախշը"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Հարցնել գաղտնաբառը"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Թարմացնե՞լ "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ծառայությունում"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Թարմացնե՞լ տվյալները (<xliff:g id="TYPE">%1$s</xliff:g>) "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ծառայությունում"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Թարմացնե՞լ տվյալները (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>) "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ծառայությունում"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Թարմացնե՞լ տվյալները (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g>) "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ծառայությունում"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Պահել"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ոչ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ոչ հիմա"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 5a9188d9cf5c..8603809903ae 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1643,7 +1643,7 @@ <string name="media_route_status_in_use" msgid="6684112905244944724">"Sedang digunakan"</string> <string name="display_manager_built_in_display_name" msgid="1015775198829722440">"Layar Built-In"</string> <string name="display_manager_hdmi_display_name" msgid="1022758026251534975">"Layar HDMI"</string> - <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Hamparan #<xliff:g id="ID">%1$d</xliff:g>"</string> + <string name="display_manager_overlay_display_name" msgid="5306088205181005861">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string> <string name="display_manager_overlay_display_title" msgid="1480158037150469170">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="2810034719482834679">", aman"</string> <string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Lupa Pola?"</string> @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Upaya ke-2 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Upaya ke-3 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> Pribadi"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Meminta PIN sebelum melepas sematan"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Meminta pola pembukaan kunci sebelum melepas sematan"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Meminta sandi sebelum melepas sematan"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Perbarui di "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Perbarui <xliff:g id="TYPE">%1$s</xliff:g> di "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Perbarui <xliff:g id="TYPE_0">%1$s</xliff:g> dan <xliff:g id="TYPE_1">%2$s</xliff:g> di "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Perbarui item-item berikut di "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, dan <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Simpan"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Lain kali"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Lain kali"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index 8ea6f6ad4228..7420a2511960 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (2)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu (3)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Afrit af <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Biðja um PIN-númer til að losa"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Biðja um opnunarmynstur til að losa"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Biðja um aðgangsorð til að losa"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Uppfæra í "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Uppfæra <xliff:g id="TYPE">%1$s</xliff:g> í "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Uppfæra <xliff:g id="TYPE_0">%1$s</xliff:g> og <xliff:g id="TYPE_1">%2$s</xliff:g> í "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Uppfæra þessi atriði í "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Vista"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nei, takk"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ekki núna"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index eb0b5698baed..168a1613fde6 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> di lavoro (2°)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> di lavoro (3°)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privato"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Richiedi il PIN per lo sblocco"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Richiedi sequenza di sblocco prima di sbloccare"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Richiedi password prima di sbloccare"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vuoi aggiornare su "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vuoi aggiornare <xliff:g id="TYPE">%1$s</xliff:g> su "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vuoi aggiornare <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> su "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vuoi aggiornare i seguenti dati in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Salva"</string> <string name="autofill_save_no" msgid="9212826374207023544">"No, grazie"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Non ora"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index a3ffd39f7eae..1f909945c79a 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1868,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> שני בעבודה"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> שלישי בעבודה"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"שכפול של <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"יש לבקש קוד אימות לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string> @@ -1956,7 +1958,7 @@ <string name="app_suspended_more_details" msgid="211260942831587014">"מידע נוסף"</string> <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"ביטול ההשהיה של האפליקציה"</string> <string name="work_mode_off_title" msgid="6367463960165135829">"להפעיל את האפליקציות לעבודה?"</string> - <string name="work_mode_turn_on" msgid="5316648862401307800">"הפעלה"</string> + <string name="work_mode_turn_on" msgid="5316648862401307800">"ביטול ההשהיה"</string> <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"שיחת חירום"</string> <string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string> <string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string> @@ -2032,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"לעדכן בשירות "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"לעדכן <xliff:g id="TYPE">%1$s</xliff:g> בשירות "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"האם לעדכן את <xliff:g id="TYPE_0">%1$s</xliff:g> ואת <xliff:g id="TYPE_1">%2$s</xliff:g> ב-"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"לעדכן את הפריטים אלה ב-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ו-<xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"שמירה"</string> <string name="autofill_save_no" msgid="9212826374207023544">"לא, תודה"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"לא עכשיו"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index aa4ac4e67d70..d7618754f200 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -321,7 +321,7 @@ <string name="permgrouplab_camera" msgid="9090413408963547706">"カメラ"</string> <string name="permgroupdesc_camera" msgid="7585150538459320326">"写真と動画の撮影"</string> <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"付近のデバイス"</string> - <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"付近のデバイスの検出と接続"</string> + <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"付近のデバイスの\\n検出と接続"</string> <string name="permgrouplab_calllog" msgid="7926834372073550288">"通話履歴"</string> <string name="permgroupdesc_calllog" msgid="2026996642917801803">"通話履歴の読み取りと書き込み"</string> <string name="permgrouplab_phone" msgid="570318944091926620">"電話"</string> @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 番目の仕事用<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 番目の仕事用<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> のクローン"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"個人用<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"オフライン再生を解除する前にPINの入力を求める"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"画面固定を解除する前にロック解除パターンの入力を求める"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"オフライン再生を解除する前にパスワードの入力を求める"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" で更新しますか?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>を "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" で更新しますか?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>を "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" で更新しますか?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>、<xliff:g id="TYPE_2">%3$s</xliff:g>を "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" で更新しますか?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"はい"</string> <string name="autofill_save_no" msgid="9212826374207023544">"いいえ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"後で"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 9e730df86610..513b392abee0 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"მე-2 სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"მე-3 სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> კლონის შექმნა"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"პირადი <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ფიქსაციის მოხსნამდე PIN-ის მოთხოვნა"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ფიქსაციის მოხსნამდე განბლოკვის ნიმუშის მოთხოვნა"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ფიქსაციის მოხსნამდე პაროლის მოთხოვნა"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"გსურთ "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"-ში განახლება?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"გსურთ, "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"-ში განაახლოთ <xliff:g id="TYPE">%1$s</xliff:g>?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"გსურთ, "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"-ში განაახლოთ <xliff:g id="TYPE_0">%1$s</xliff:g> და <xliff:g id="TYPE_1">%2$s</xliff:g>?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"განახლდეს ეს ერთეულები "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-ში: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> და <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"შენახვა"</string> <string name="autofill_save_no" msgid="9212826374207023544">"არა, გმადლობთ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ახლა არა"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 15610456753e..1d93a71f14c5 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-ші жұмыс профилі (<xliff:g id="LABEL">%1$s</xliff:g>)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клондау"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Босату алдында PIN кодын сұрау"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" қызметінде жаңартылсын ба?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> деректері "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" қызметінде жаңартылсын ба?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> және <xliff:g id="TYPE_1">%2$s</xliff:g> деректері "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" қызметінде жаңартылсын ба?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" қызметіндегі <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> және <xliff:g id="TYPE_2">%3$s</xliff:g> деректері жаңартылсын ба?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Сақтау"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Жоқ, рақмет"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Қазір емес"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index cea9af4ae439..9047666092a5 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> ការងារទី 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> ការងារទី 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"ក្លូន <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> ឯកជន"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"សួររកកូដ PIN មុនពេលដកខ្ទាស់"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"សួររកលំនាំដោះសោមុនពេលដោះខ្ទាស់"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"សួររកពាក្យសម្ងាត់មុនពេលផ្ដាច់"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"ធ្វើបច្ចុប្បន្នភាពនៅក្នុង "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"ធ្វើបច្ចុប្បន្នភាព <xliff:g id="TYPE">%1$s</xliff:g> នៅក្នុង "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"ធ្វើបច្ចុប្បន្នភាព <xliff:g id="TYPE_0">%1$s</xliff:g> និង <xliff:g id="TYPE_1">%2$s</xliff:g> នៅក្នុង "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ធ្វើបច្ចុប្បន្នភាពធាតុទាំងនេះនៅក្នុង "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"៖ <xliff:g id="TYPE_0">%1$s</xliff:g> <xliff:g id="TYPE_1">%2$s</xliff:g> និង<xliff:g id="TYPE_2">%3$s</xliff:g>ឬ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"រក្សាទុក"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ទេ អរគុណ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"កុំទាន់"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 4cdb755669f8..19c6f5d20491 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 ನೇ ಕೆಲಸದ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 ನೇ ಕೆಲಸದ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ಕ್ಲೋನ್"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"ಖಾಸಗಿ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಿನ್ ಕೇಳು"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ಅನ್ಪಿನ್ ಮಾಡಲು ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಕೇಳಿ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ಅನ್ಪಿನ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳು"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ನಲ್ಲಿ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೆ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> ಅನ್ನು "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ನಲ್ಲಿ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೆ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="TYPE_1">%2$s</xliff:g> ಅನ್ನು "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ನಲ್ಲಿ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೆ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ಈ ಮುಂದಿನ ಐಟಂಗಳನ್ನು "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ನಲ್ಲಿ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೆ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ಮತ್ತು <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ಉಳಿಸಿ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ಬೇಡ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ಸದ್ಯಕ್ಕೆ ಬೇಡ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index ae92aa951dee..335a9572a866 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"두 번째 업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"세 번째 업무용<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> 복사"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"고정 해제 이전에 PIN 요청"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"에서 업데이트하시겠습니까?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"에서 <xliff:g id="TYPE">%1$s</xliff:g>을(를) 업데이트하시겠습니까?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"에서 <xliff:g id="TYPE_0">%1$s</xliff:g> 및 <xliff:g id="TYPE_1">%2$s</xliff:g>을(를) 업데이트하시겠습니까?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"에서 <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> 항목을 업데이트하시겠습니까?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"저장"</string> <string name="autofill_save_no" msgid="9212826374207023544">"사용 안함"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"나중에"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index c585841dfd7d..df4929fac5b8 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> клону"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бошотуудан мурун PIN суралсын"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бошотуудан мурун графикалык ачкыч суралсын"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Бошотуудан мурун сырсөз суралсын"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" кызматында жаңыртылсынбы?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" кызматындагы <xliff:g id="TYPE">%1$s</xliff:g> жаңыртылсын?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" кызматындагы <xliff:g id="TYPE_0">%1$s</xliff:g> жана <xliff:g id="TYPE_1">%2$s</xliff:g> жаңыртылсынбы?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" кызматындагы төмөнкүлөр жаңыртылсынбы: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> жана <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Сактоо"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Жок, рахмат"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Азыр эмес"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 8057449d27fb..cddabaf3afa6 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ບ່ອນເຮັດວຽກທີ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ບ່ອນເຮັດວຽກທີ 3 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"ໂຄລນ <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ຖາມຫາ PIN ກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ຖາມຫາຮູບແບບປົດລັອກກ່ອນຍົກເລີກການປັກໝຸດ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ຖາມຫາລະຫັດຜ່ານກ່ອນຍົກເລີກການປັກໝຸດ"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"ອັບເດດໃນ "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ບໍ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"ອັບເດດ <xliff:g id="TYPE">%1$s</xliff:g> ໃນ "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ບໍ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"ອັບເດດ <xliff:g id="TYPE_0">%1$s</xliff:g> ແລະ <xliff:g id="TYPE_1">%2$s</xliff:g> ໃນ "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ບໍ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ອັບເດດລາຍການເຫຼົ່ານີ້ໃນ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ແລະ <xliff:g id="TYPE_2">%3$s</xliff:g> ບໍ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ບັນທຶກ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ບໍ່, ຂອບໃຈ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ບໍ່ຟ້າວເທື່ອ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index c6d36d1d1828..33168458ffb9 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1869,6 +1869,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-asis darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-iasis darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"„<xliff:g id="LABEL">%1$s</xliff:g>“ kopija"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privat. „<xliff:g id="LABEL">%1$s</xliff:g>“"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Prašyti PIN kodo prieš atsegant"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Prašyti atrakinimo piešinio prieš atsegant"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Prašyti slaptažodžio prieš atsegant"</string> @@ -2033,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Atnaujinti paslaugoje "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Atnaujinti <xliff:g id="TYPE">%1$s</xliff:g> paslaugoje "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Atnaujinti <xliff:g id="TYPE_0">%1$s</xliff:g> ir <xliff:g id="TYPE_1">%2$s</xliff:g> paslaugoje "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Atnaujinti šiuos elementus paslaugoje "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ir <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Išsaugoti"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, ačiū"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne dabar"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 45b9586dfd1f..fb1b7b9d5aef 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1868,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. darba profils: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (klons)"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Prasīt PIN kodu pirms atspraušanas"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string> @@ -2032,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vai atjaunināt informāciju pakalpojumā "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vai atjaunināt informāciju <xliff:g id="TYPE">%1$s</xliff:g> pakalpojumā "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vai atjaunināt informāciju <xliff:g id="TYPE_0">%1$s</xliff:g> un <xliff:g id="TYPE_1">%2$s</xliff:g> pakalpojumā "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vai atjaunināt šos vienumus pakalpojumā "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> un <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Saglabāt"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nē, paldies"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Vēlāk"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 33e9a55e5bec..ae0a0350a34b 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Втора деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Трета деловна <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонирајте го <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Приватен <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Побарај PIN пред откачување"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Да се ажурира во "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Да се ажурира <xliff:g id="TYPE">%1$s</xliff:g> во "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Да се ажурираат <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> во "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Да се ажурираат овие ставки во "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Зачувај"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Не, фала"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сега"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 8a4ddf10c5ad..80e80618185e 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"രണ്ടാമത്തെ ഔദ്യോഗിക <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"മൂന്നാമത്തെ ഔദ്യോഗിക <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"ക്ലോൺ <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"സ്വകാര്യം <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ചെയ്യുംമുമ്പ് പിൻ ചോദിക്കൂ"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"അൺപിന്നിനുമുമ്പ് അൺലോക്ക് പാറ്റേൺ ആവശ്യപ്പെടൂ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"അൺപിന്നിനുമുമ്പ് പാസ്വേഡ് ആവശ്യപ്പെടൂ"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" എന്നതിൽ അപ്ഡേറ്റ് ചെയ്യണോ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>, "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" എന്നതിൽ അപ്ഡേറ്റ് ചെയ്യണോ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> എന്നിവ "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" എന്നതിൽ അപ്ഡേറ്റ് ചെയ്യണോ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ഇനിപ്പറയുന്ന ഇനങ്ങൾ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" എന്നതിൽ അപ്ഡേറ്റ് ചെയ്യണോ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"സംരക്ഷിക്കുക"</string> <string name="autofill_save_no" msgid="9212826374207023544">"വേണ്ട, നന്ദി"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ഇപ്പോൾ വേണ്ട"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index 8332bb12e99c..d2bdb4d431af 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -971,7 +971,7 @@ <string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Тайлах хээгээ зурна уу"</string> <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Яаралтай тусламж"</string> <string name="lockscreen_return_to_call" msgid="3156883574692006382">"Дуудлагаруу буцах"</string> - <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Зөв!"</string> + <string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Зөв"</string> <string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Дахин оролдох"</string> <string name="lockscreen_password_wrong" msgid="8605355913868947490">"Дахин оролдох"</string> <string name="lockscreen_storage_locked" msgid="634993789186443380">"Бүх онцлог, өгөгдлийн түгжээг тайлах"</string> @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 дахь ажил <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клон <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Хувийн <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Бэхэлснийг болиулахаасаа өмнө ПИН асуух"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"-д шинэчлэх үү?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>-г "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"-д шинэчлэх үү?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> болон <xliff:g id="TYPE_1">%2$s</xliff:g>-г "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"-д шинэчлэх үү?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"-н эдгээр зүйлийг шинэчлэх: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> болон <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Хадгалах"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Үгүй, баярлалаа"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Одоо биш"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index effddd6745e0..5f7a5c14e984 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3 रे कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन केलेले"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन करण्यापूर्वी पिन विचारा"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्यापूर्वी संकेतशब्दासाठी विचारा"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" मध्ये अपडेट करायचे का?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>, "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" मध्ये अपडेट करायचे का?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> आणि <xliff:g id="TYPE_1">%2$s</xliff:g>, "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" मध्ये अपडेट करायचे का?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"हे आयटम "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> आणि <xliff:g id="TYPE_2">%3$s</xliff:g> मध्ये अपडेट करायचे आहेत का?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"सेव्ह करा"</string> <string name="autofill_save_no" msgid="9212826374207023544">"नाही, नको"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"आता नको"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index bcaa06dbff08..74e904dab535 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> kerja ke-2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> kerja ke-3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> Klon"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> Peribadi"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Minta PIN sebelum menyahsemat"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Minta corak buka kunci sebelum menyahsemat"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Minta kata laluan sebelum menyahsemat"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Kemas kini dalam "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Kemas kini <xliff:g id="TYPE">%1$s</xliff:g> dalam "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Kemas kini <xliff:g id="TYPE_0">%1$s</xliff:g> dan <xliff:g id="TYPE_1">%2$s</xliff:g> dalam "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Kemas kinikan item ini dalam "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> dan <xliff:g id="TYPE_2">%3$s</xliff:g> ?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Simpan"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Tidak perlu"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Bukan sekarang"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 924bfe044bff..394a74e64752 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ဒုတိယအလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"တတိယအလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ပုံတူပွား"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"သီးသန့် <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ပင်မဖြုတ်မီမှာ PIN ကို မေးကြည့်ရန်"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ပင်မဖြုတ်မီမှာ သော့ဖွင့် ရေးဆွဲမှုပုံစံကို မေးကြည့်ရန်"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"တွင် အပ်ဒိတ်လုပ်လိုပါသလား။"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> ကို "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" တွင် အပ်ဒိတ်လုပ်လိုပါသလား။"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> နှင့် <xliff:g id="TYPE_1">%2$s</xliff:g> ကို "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"တွင် အပ်ဒိတ်လုပ်လိုပါသလား။"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ဤအရာများကို "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" တွင် အပ်ဒိတ်လုပ်မလား- <xliff:g id="TYPE_0">%1$s</xliff:g>၊ <xliff:g id="TYPE_1">%2$s</xliff:g> နှင့် <xliff:g id="TYPE_2">%3$s</xliff:g>။"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"သိမ်းရန်"</string> <string name="autofill_save_no" msgid="9212826374207023544">"မလိုပါ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ယခုမလုပ်ပါ"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 7ae201cfd859..ffc8bea2894b 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andre <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> for jobben"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Krev PIN-kode for å løsne app"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vil du oppdatere i "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vil du oppdatere <xliff:g id="TYPE">%1$s</xliff:g> i "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vil du oppdatere <xliff:g id="TYPE_0">%1$s</xliff:g> og <xliff:g id="TYPE_1">%2$s</xliff:g> i "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vil du oppdatere disse elementene i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> og <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Lagre"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nei takk"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ikke nå"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 7d6d09fc5855..672cfbc8a633 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"कार्यालयको दोस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"कार्यालयको तेस्रो <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> क्लोन गर्नुहोस्"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"अनपिन गर्नुअघि PIN मागियोस्"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" मा अद्यावधिक गर्ने हो?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> लाई "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" मा अद्यावधिक गर्ने हो?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> र <xliff:g id="TYPE_1">%2$s</xliff:g> लाई "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" मा अद्यावधिक गर्ने हो?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"तपाईं "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" मा भएका निम्न वस्तुहरू अपडेट गर्न चाहनुहुन्छ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> र <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"सेभ गर्नुहोस्"</string> <string name="autofill_save_no" msgid="9212826374207023544">"पर्दैन, धन्यवाद"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"अहिले होइन"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index f92b3941670a..2846b6a115b0 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3e <xliff:g id="LABEL">%1$s</xliff:g>, werk"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Kloon van <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Privé <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Vraag pin voor losmaken"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vraag om ontgrendelingspatroon voor losmaken"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vraag wachtwoord voor losmaken"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Updaten in "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> updaten in "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> en <xliff:g id="TYPE_1">%2$s</xliff:g> updaten in "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Deze items updaten in "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> en <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Opslaan"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nee, bedankt"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Niet nu"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index b94ab7560199..41d8b509b1fa 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3ୟ କାର୍ଯ୍ୟ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> କ୍ଲୋନ"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ଅନପିନ୍ କରିବା ପୂର୍ବରୁ PIN ପଚାରନ୍ତୁ"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍ କରିବା ପୂର୍ବରୁ ଲକ୍ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍ କରିବା ପୂର୍ବରୁ ପାସ୍ୱର୍ଡ ପଚାରନ୍ତୁ"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"ରେ ଅପ୍ଡେଟ୍ କରିବେ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"ରେ <xliff:g id="TYPE">%1$s</xliff:g>କୁ ଅପ୍ଡେଟ୍ କରିବେ।"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"ରେ <xliff:g id="TYPE_0">%1$s</xliff:g> ଏବଂ <xliff:g id="TYPE_1">%2$s</xliff:g> ଅପ୍ଡେଟ୍ କରିବେ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"ରେ ଏହି ଆଇଟମଗୁଡ଼ିକୁ ଅପଡେଟ କରିବେ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ଏବଂ <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ସେଭ୍ କରନ୍ତୁ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ନାଁ, ପଚାରିଥିବାରୁ ଧନ୍ୟବାଦ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ଏବେ ନୁହେଁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index c17b17b23648..8b9934fe860b 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"ਦੂਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"ਤੀਸਰੀ ਕਾਰਜ-ਸਥਾਨ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ਦਾ ਕਲੋਨ"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਿੰਨ ਮੰਗੋ"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"ਕੀ ਤੁਸੀਂ "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ਵਿੱਚ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"ਕੀ ਤੁਸੀਂ "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ਵਿੱਚ <xliff:g id="TYPE">%1$s</xliff:g> ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"ਕੀ ਤੁਸੀਂ "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ਵਿੱਚ <xliff:g id="TYPE_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="TYPE_1">%2$s</xliff:g> ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ਕੀ ਤੁਸੀਂ "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ਵਿੱਚ ਇਨ੍ਹਾਂ ਆਈਟਮਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ਅਤੇ<xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"ਰੱਖਿਅਤ ਕਰੋ"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ਨਹੀਂ ਧੰਨਵਾਦ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ਹੁਣੇ ਨਹੀਂ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 45353b180c49..880892f9e786 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1869,6 +1869,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> – praca 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon aplikacji <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Podaj PIN, aby odpiąć"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string> @@ -2033,8 +2035,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Zaktualizować w: "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Zaktualizować: <xliff:g id="TYPE">%1$s</xliff:g> w: "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Zaktualizować: <xliff:g id="TYPE_0">%1$s</xliff:g> i <xliff:g id="TYPE_1">%2$s</xliff:g> w: "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Zaktualizować w "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" te elementy: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> i <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Zapisz"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nie, dziękuję"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Nie teraz"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index d4f35295c7c1..70f80a81750b 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Segundo <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Terceiro <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> particular"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de liberar"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Atualizar em "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Atualizar <xliff:g id="TYPE">%1$s</xliff:g> em "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Atualizar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Atualizar estes itens em "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Salvar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Agora não"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 53fbfd3a32f0..7341500d8b46 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3.º <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonar <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> privado"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de soltar"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de soltar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir palavra-passe antes de soltar"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Quer atualizar em "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Quer atualizar <xliff:g id="TYPE">%1$s</xliff:g> em "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Quer atualizar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Atualizar estes itens no serviço "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Não, obrigado"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index d4f35295c7c1..70f80a81750b 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Segundo <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Terceiro <xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> (clone)"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> particular"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pedir PIN antes de liberar"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Atualizar em "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Atualizar <xliff:g id="TYPE">%1$s</xliff:g> em "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Atualizar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Atualizar estes itens em "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Salvar"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Agora não"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index ce0eb91f23e1..5dc54639d14c 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -670,14 +670,10 @@ </string-array> <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"A apărut o eroare. Încearcă din nou."</string> <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string> - <!-- no translation found for device_unlock_notification_name (2632928999862915709) --> - <skip /> - <!-- no translation found for alternative_unlock_setup_notification_title (6241508547901933544) --> - <skip /> - <!-- no translation found for alternative_face_setup_notification_content (3384959224091897331) --> - <skip /> - <!-- no translation found for alternative_fp_setup_notification_content (7454096947415721639) --> - <skip /> + <string name="device_unlock_notification_name" msgid="2632928999862915709">"Deblocarea dispozitivului"</string> + <string name="alternative_unlock_setup_notification_title" msgid="6241508547901933544">"Încearcă o altă modalitate de deblocare"</string> + <string name="alternative_face_setup_notification_content" msgid="3384959224091897331">"Folosește Deblocarea facială atunci când amprenta ta nu este recunoscută, de exemplu, când ai degetele ude"</string> + <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"Folosește Deblocarea cu amprenta atunci când chipul tău nu este recunoscut, de exemplu, când nu există suficientă lumină"</string> <string name="face_recalibrate_notification_name" msgid="7311163114750748686">"Deblocare facială"</string> <string name="face_recalibrate_notification_title" msgid="2524791952735579082">"Problemă cu Deblocarea facială"</string> <string name="face_recalibrate_notification_content" msgid="3064513770251355594">"Atinge pentru a șterge modelul facial, apoi adaugă din nou chipul"</string> @@ -1872,6 +1868,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (2)"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> pentru serviciu (3)"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Clonă pentru <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Solicită codul PIN înainte de a anula fixarea"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string> @@ -2036,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Actualizezi în "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Actualizezi <xliff:g id="TYPE">%1$s</xliff:g> în "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Actualizezi <xliff:g id="TYPE_0">%1$s</xliff:g> și <xliff:g id="TYPE_1">%2$s</xliff:g> în "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Actualizezi aceste articole în "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> și <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Salvează"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nu, mulțumesc"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Nu acum"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 155f654faf98..e09593ee95c3 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1869,6 +1869,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Задача 2: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Задача 3: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонировать <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Запрашивать PIN-код"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string> @@ -2033,8 +2035,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Обновить в сервисе "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Обновить данные (<xliff:g id="TYPE">%1$s</xliff:g>) в сервисе "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Обновить данные (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>) в сервисе "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Обновить данные (<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, <xliff:g id="TYPE_2">%3$s</xliff:g>) в сервисе "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Сохранить"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Нет, спасибо"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сейчас"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 748501262381..99d90bee006b 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3වන වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> ක්ලෝන කරන්න"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ගැලවීමට පෙර PIN විමසන්න"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" තුළ යාවත්කාලීන කරන්නද?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" තුළ <xliff:g id="TYPE">%1$s</xliff:g> යාවත්කාලීන කරන්නද?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" තුළ <xliff:g id="TYPE_0">%1$s</xliff:g> සහ <xliff:g id="TYPE_1">%2$s</xliff:g> යාවත්කාලීන කරන්නද?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, සහ <xliff:g id="TYPE_2">%3$s</xliff:g> තුළ මෙම අයිතම යාවත්කාලීන කරන්න ද?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"සුරකින්න"</string> <string name="autofill_save_no" msgid="9212826374207023544">"එපා ස්තූතියි"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"දැන් නොවේ"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index c06c7cc8b8f3..a3ca1a6562f3 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1869,6 +1869,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. <xliff:g id="LABEL">%1$s</xliff:g> do práce"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonovať <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Pred odopnutím požiadať o číslo PIN"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred uvoľnením požiadať o bezpečnostný vzor"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odopnutím požiadať o heslo"</string> @@ -2033,8 +2035,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Aktualizovať v službe "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Chcete údaje <xliff:g id="TYPE">%1$s</xliff:g> aktualizovať v službe "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Chcete položky <xliff:g id="TYPE_0">%1$s</xliff:g> a <xliff:g id="TYPE_1">%2$s</xliff:g> aktualizovať v službe "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Chcete tieto položky aktualizovať v službe "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> a <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Uložiť"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nie, vďaka"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Teraz nie"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index c25e052bb632..5292fc328640 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1869,6 +1869,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. službeni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. službeni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klon aplikacije <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Zasebni <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Zahtevaj PIN pred odpenjanjem"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pred odpenjanjem vprašaj za geslo"</string> @@ -2033,8 +2034,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Želite posodobiti v aplikaciji "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Želite posodobiti element <xliff:g id="TYPE">%1$s</xliff:g> v aplikaciji "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Želite posodobiti elementa <xliff:g id="TYPE_0">%1$s</xliff:g> in <xliff:g id="TYPE_1">%2$s</xliff:g> v aplikaciji "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Želite posodobiti te elemente v "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> in <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Shrani"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ne, hvala"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Ne zdaj"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index c93b69958052..fd7453426231 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> i dytë i punës"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> i tretë i punës"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klonim i <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Zhgozhdimi kërkon PIN-in"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Të përditësohet në "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Të përditësohet <xliff:g id="TYPE">%1$s</xliff:g> në "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Të përditësohet <xliff:g id="TYPE_0">%1$s</xliff:g> dhe <xliff:g id="TYPE_1">%2$s</xliff:g> në "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Të përditësohen këta artikuj në "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> dhe <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Ruaj"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Jo, faleminderit"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Jo tani"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 14dfac53966d..81c19152f0fb 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -494,7 +494,7 @@ <string name="permdesc_sim_communication" msgid="4179799296415957960">"Омогућава апликацији да шаље команде SIM картици. То је веома опасно."</string> <string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string> <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string> - <string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видео снимака"</string> + <string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видеа"</string> <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string> <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string> <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string> @@ -745,8 +745,8 @@ <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Омогућава апликацији да чита видео фајлове из дељеног меморијског простора."</string> <string name="permlab_readMediaImages" msgid="4057590631020986789">"читање фајлова слика из дељеног меморијског простора"</string> <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Омогућава апликацији да чита фајлове слика из дељеног меморијског простора."</string> - <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"читање фајлова слика и видео снимака које корисник бира из дељеног меморијског простора"</string> - <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Омогућава апликацији да чита фајлове слика и видео снимака које изаберете из дељеног меморијског простора."</string> + <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"читање фајлова слика и видеа које корисник бира из дељеног меморијског простора"</string> + <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Омогућава апликацији да чита фајлове слика и видеа које изаберете из дељеног меморијског простора."</string> <string name="permlab_sdcardWrite" msgid="4863021819671416668">"мењање или брисање садржаја дељеног меморијског простора"</string> <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Дозвољава апликацији да уписује садржај дељеног меморијског простора."</string> <string name="permlab_use_sip" msgid="8250774565189337477">"упућивање/пријем SIP позива"</string> @@ -1172,7 +1172,7 @@ <string name="app_running_notification_text" msgid="5120815883400228566">"Додирните за више информација или заустављање апликације."</string> <string name="ok" msgid="2646370155170753815">"Потврди"</string> <string name="cancel" msgid="6908697720451760115">"Откажи"</string> - <string name="yes" msgid="9069828999585032361">"Потврди"</string> + <string name="yes" msgid="9069828999585032361">"У реду"</string> <string name="no" msgid="5122037903299899715">"Откажи"</string> <string name="dialog_alert_title" msgid="651856561974090712">"Пажња"</string> <string name="loading" msgid="3138021523725055037">"Учитава се…"</string> @@ -1417,7 +1417,7 @@ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Додирните да бисте подесили"</string> <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Изаберите да бисте подесили"</string> <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Можда морате да реформатирате уређај. Додирните да бисте избацили."</string> - <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"За чување слика, видео снимака, музике и другог садржаја"</string> + <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"За чување слика, видеа, музике и другог садржаја"</string> <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"Прегледајте медијске фајлове"</string> <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"Проблем са: <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> не ради"</string> @@ -1868,6 +1868,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2. пословни <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3. пословни имејл <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Клонирај <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Приватни <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Тражи PIN пре откачињања"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string> @@ -2032,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Желите ли да ажурирате у услузи "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Желите ли да ажурирате ставку <xliff:g id="TYPE">%1$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Желите ли да ажурирате ставке <xliff:g id="TYPE_0">%1$s</xliff:g> и <xliff:g id="TYPE_1">%2$s</xliff:g> у услузи "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Желите ли да ажурирате ове ставке у услузи "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> и <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Сачувај"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Не, хвала"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не сада"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 8d0a41f4f27b..1ca3e08abb53 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Andra <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Tredje <xliff:g id="LABEL">%1$s</xliff:g> för jobbet"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Klona <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Be om pinkod innan skärmen slutar fästas"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Be om upplåsningsmönster innan skärmen slutar fästas"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Be om lösenord innan skärmen slutar fästas"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Vill du uppdatera detta i "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Vill du uppdatera <xliff:g id="TYPE">%1$s</xliff:g> i "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Vill du uppdatera <xliff:g id="TYPE_0">%1$s</xliff:g> och <xliff:g id="TYPE_1">%2$s</xliff:g> i "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Vill du uppdatera dessa objekt i "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> och <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Spara"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Nej tack"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Inte nu"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index afc1fc3b78e1..1ec2eeff1575 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> ya 2 ya Kazini"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> ya 3 ya Kazini"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Nakala ya <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Faragha <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Itisha PIN kabla hujabandua"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Omba mchoro wa kufungua kabla hujabandua"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Omba nenosiri kabla hujabandua"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Ungependa kusasisha katika "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Ungependa kusasisha <xliff:g id="TYPE">%1$s</xliff:g> katika "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Ungependa kusasisha <xliff:g id="TYPE_0">%1$s</xliff:g> na <xliff:g id="TYPE_1">%2$s</xliff:g> katika "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Ungependa kusasisha vipengee hivi katika "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> na <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Hifadhi"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Hapana"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Si sasa"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index 6052b4f98b4e..5b2b2b2d522a 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3வது பணி <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"குளோன் <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"அகற்றும் முன் PINஐக் கேள்"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" இல் மாற்றவா?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" இல் <xliff:g id="TYPE">%1$s</xliff:g>ஐ மாற்றவா?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273"><b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" இல் <xliff:g id="TYPE_0">%1$s</xliff:g> மற்றும் <xliff:g id="TYPE_1">%2$s</xliff:g>ஐ மாற்றவா?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" இல் <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> மற்றும் <xliff:g id="TYPE_2">%3$s</xliff:g>ஐ மாற்றவா?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"சேமி"</string> <string name="autofill_save_no" msgid="9212826374207023544">"வேண்டாம்"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"இப்போது வேண்டாம்"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 9da39c334b7d..5b9e737b7d63 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2వ కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3వ కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"క్లోన్ <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"ప్రైవేట్ <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"అన్పిన్ చేయడానికి ముందు పిన్ కోసం అడుగు"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"అన్పిన్ చేయడానికి ముందు అన్లాక్ ఆకృతి కోసం అడుగు"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"లో అప్డేట్ చేయాలా?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g>ని "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"లో అప్డేట్ చేయాలా?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> మరియు <xliff:g id="TYPE_1">%2$s</xliff:g>ని "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"లో అప్డేట్ చేయాలా?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ఈ ఐటెమ్లను "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"లో అప్డేట్ చేయండి: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> అలాగే <xliff:g id="TYPE_2">%3$s</xliff:g> అప్డేట్ చేయాలా?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"సేవ్ చేయండి"</string> <string name="autofill_save_no" msgid="9212826374207023544">"వద్దు, ధన్యవాదాలు"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ఇప్పుడు కాదు"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index fa6638074c89..804562a90f62 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"<xliff:g id="LABEL">%1$s</xliff:g> งานที่ 2"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"<xliff:g id="LABEL">%1$s</xliff:g> งานที่ 3"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"โคลน <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"<xliff:g id="LABEL">%1$s</xliff:g> ส่วนตัว"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"ขอ PIN ก่อนเลิกปักหมุด"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ขอรูปแบบการปลดล็อกก่อนเลิกปักหมุด"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ขอรหัสผ่านก่อนเลิกปักหมุด"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"อัปเดตใน "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ไหม"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"อัปเดต<xliff:g id="TYPE">%1$s</xliff:g>ใน "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" ไหม"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"อัปเดต<xliff:g id="TYPE_0">%1$s</xliff:g>และ<xliff:g id="TYPE_1">%2$s</xliff:g>ใน "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" ไหม"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"อัปเดตข้อมูล<xliff:g id="TYPE_0">%1$s</xliff:g> <xliff:g id="TYPE_1">%2$s</xliff:g> และ<xliff:g id="TYPE_2">%3$s</xliff:g>ใน "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" ไหม"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"บันทึก"</string> <string name="autofill_save_no" msgid="9212826374207023544">"ไม่เป็นไร"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ไว้ทีหลัง"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 840810cf9ab2..51e7ec641e1b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Pangalawang <xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Pangatlong <xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"I-clone ang <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Pribadong <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Humingi ng PIN bago mag-unpin"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Humingi ng pattern sa pag-unlock bago mag-unpin"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Humingi ng password bago mag-unpin"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"I-update sa "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"I-update ang <xliff:g id="TYPE">%1$s</xliff:g> sa "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"I-update ang <xliff:g id="TYPE_0">%1$s</xliff:g> at <xliff:g id="TYPE_1">%2$s</xliff:g> sa "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"I-update ang mga item na ito sa "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, at <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"I-save"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Hindi, salamat na lang"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Hindi ngayon"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 90a57311840f..33b050aa2cef 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"İş için 2. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"İş için 3. <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> klonu"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Sabitlemeyi kaldırmadan önce PIN\'i sor"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" hizmetinde güncellensin mi?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" hizmetinde güncellensin mi?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> ve <xliff:g id="TYPE_1">%2$s</xliff:g> "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" hizmetinde güncellensin mi?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Şu öğeler "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" hizmetinde güncellensin mi: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> ve <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Kaydet"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Hayır, teşekkürler"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Şimdi değil"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index f8a725daaaaf..f6d426d53b28 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1869,6 +1869,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-а робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-я робота: <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Копія додатка <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"PIN-код для відкріплення"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string> @@ -2033,8 +2035,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Оновити в сервісі "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Оновити дані (<xliff:g id="TYPE">%1$s</xliff:g>) у сервісі "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Оновити дані (<xliff:g id="TYPE_0">%1$s</xliff:g> і <xliff:g id="TYPE_1">%2$s</xliff:g>) у сервісі "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Оновити в сервісі "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" такі дані: <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> і <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Зберегти"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Ні, дякую"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Не зараз"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index 227f25d4bf87..c8cd1cb2b9d9 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"دوسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"تیسرا کام <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> کلون"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"پن ہٹانے سے پہلے PIN طلب کریں"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"پن ہٹانے سے پہلے غیر مقفل کرنے کا پیٹرن طلب کریں"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"پن ہٹانے سے پہلے پاس ورڈ طلب کریں"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" میں اپ ڈیٹ کریں؟"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704"><b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" میں <xliff:g id="TYPE">%1$s</xliff:g> اپ ڈیٹ کریں؟"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> اور <xliff:g id="TYPE_1">%2$s</xliff:g> کو "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" میں اپ ڈیٹ کریں؟"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"ان آئٹمز کو "<b>"<xliff:g id="LABEL">%4$s</xliff:g> "</b>" میں اپ ڈیٹ کریں: <xliff:g id="TYPE_0">%1$s</xliff:g>، <xliff:g id="TYPE_1">%2$s</xliff:g> اور <xliff:g id="TYPE_2">%3$s</xliff:g>؟"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"محفوظ کریں"</string> <string name="autofill_save_no" msgid="9212826374207023544">"نہیں، شکریہ"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"ابھی نہیں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index a0b43c7bb15e..696edd384309 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"2-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"3-ishxona <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g> nusxasini yaratish"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Shaxsiy <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Yechishda PIN kod talab qilinsin"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Yechishdan oldin grafik kalit so‘ralsin"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bo‘shatishdan oldin parol so‘ralsin"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136"><b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" xizmatida yangilansinmi?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"<xliff:g id="TYPE">%1$s</xliff:g> "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" xizmatida yangilansinmi?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"<xliff:g id="TYPE_0">%1$s</xliff:g> va <xliff:g id="TYPE_1">%2$s</xliff:g> "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" xizmatida yangilansinmi?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626"><b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" xizmatidagi <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> va <xliff:g id="TYPE_2">%3$s</xliff:g> yangilansinmi?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Saqlash"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Kerak emas"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Keyinroq"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f6abefbb2959..5b92609c8b96 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1867,6 +1867,8 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Công việc thứ 2 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"Sao chép <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <!-- no translation found for private_profile_label_badge (1712086003787839183) --> + <skip /> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Hỏi mã PIN trước khi bỏ ghim"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string> @@ -2031,8 +2033,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Cập nhật trong "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Cập nhật <xliff:g id="TYPE">%1$s</xliff:g> trong "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Cập nhật <xliff:g id="TYPE_0">%1$s</xliff:g> và <xliff:g id="TYPE_1">%2$s</xliff:g> trong "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Cập nhật các mục <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> và <xliff:g id="TYPE_2">%3$s</xliff:g> trong "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Lưu"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Không, cảm ơn"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Để sau"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 10d865b64d12..f900b59c8eba 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第二个工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第三个工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"<xliff:g id="LABEL">%1$s</xliff:g>克隆"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"私人“<xliff:g id="LABEL">%1$s</xliff:g>”"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消时要求输入PIN码"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消时要求绘制解锁图案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消时要求输入密码"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"要在"<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"中更新吗?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"要在"<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"中更新<xliff:g id="TYPE">%1$s</xliff:g>吗?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"要在"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"中更新<xliff:g id="TYPE_0">%1$s</xliff:g>和<xliff:g id="TYPE_1">%2$s</xliff:g>吗?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"要在"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>"中更新<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>吗?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"保存"</string> <string name="autofill_save_no" msgid="9212826374207023544">"不用了"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"以后再说"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 8de69311ad7e..7140539391e7 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第二個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第三個工作<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"複製 <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"私人<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"要在 "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" 中更新嗎?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"要在 "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" 中更新<xliff:g id="TYPE">%1$s</xliff:g>嗎?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"要在 "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" 中更新<xliff:g id="TYPE_0">%1$s</xliff:g>和<xliff:g id="TYPE_1">%2$s</xliff:g>嗎?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"要在 "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" 中更新<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>嗎?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"儲存"</string> <string name="autofill_save_no" msgid="9212826374207023544">"不用了,謝謝"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"暫時不要"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index c0631e9a72a2..61fe93977e92 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"第 2 項工作:<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"第 3 項工作:<xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"複製<xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"私人 <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"取消固定時必須輸入 PIN"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須畫出解鎖圖案"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"要更新 "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" 中的內容嗎?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"要更新 "<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>" 中的<xliff:g id="TYPE">%1$s</xliff:g>嗎?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"要更新 "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>" 中的<xliff:g id="TYPE_0">%1$s</xliff:g>和<xliff:g id="TYPE_1">%2$s</xliff:g>嗎?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"要更新 "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>" 中的<xliff:g id="TYPE_0">%1$s</xliff:g>、<xliff:g id="TYPE_1">%2$s</xliff:g>和<xliff:g id="TYPE_2">%3$s</xliff:g>嗎?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"儲存"</string> <string name="autofill_save_no" msgid="9212826374207023544">"不用了,謝謝"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"暫時不要"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index e9b408048793..77a41fce44e3 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1867,6 +1867,7 @@ <string name="managed_profile_label_badge_2" msgid="5673187309555352550">"Umsebenzi wesibili <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge_3" msgid="6882151970556391957">"Umsebenzi wesithathu <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="clone_profile_label_badge" msgid="1871997694718793964">"I-Clone <xliff:g id="LABEL">%1$s</xliff:g>"</string> + <string name="private_profile_label_badge" msgid="1712086003787839183">"Okuyimfihlo <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_unlock_pin" msgid="3890940811866290782">"Cela iphinikhodi ngaphambi kokuphina"</string> <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string> <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string> @@ -2031,8 +2032,7 @@ <string name="autofill_update_title" msgid="3630695947047069136">"Buyekeza ku-"<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_type" msgid="5264152633488495704">"Buyekeza i-<xliff:g id="TYPE">%1$s</xliff:g> ku-"<b>"<xliff:g id="LABEL">%2$s</xliff:g>"</b>"?"</string> <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Buyekeza i-<xliff:g id="TYPE_0">%1$s</xliff:g> ne-<xliff:g id="TYPE_1">%2$s</xliff:g> ku-"<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string> - <!-- no translation found for autofill_update_title_with_3types (8285767070604652626) --> - <skip /> + <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Buyekeza lezi zinto ku-"<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g>, ne-<xliff:g id="TYPE_2">%3$s</xliff:g>?"</string> <string name="autofill_save_yes" msgid="8035743017382012850">"Londoloza"</string> <string name="autofill_save_no" msgid="9212826374207023544">"Cha ngiyabonga"</string> <string name="autofill_save_notnow" msgid="2853932672029024195">"Hhayi manje"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a72f779bf70c..302c7fad8173 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1185,6 +1185,9 @@ --> <integer name="config_shortPressOnSleepBehavior">0</integer> + <!-- Whether to silence telephony ringer on sleep key event --> + <bool name="config_silenceRingerOnSleepKey">false</bool> + <!-- Control the behavior when the user long presses the stem primary button. Stem primary button is only used on watch form factor. If a device is not a watch, setting this config is no-op. @@ -5477,6 +5480,13 @@ of known compatibility issues. --> <string-array name="config_highRefreshRateBlacklist"></string-array> + <!-- The list of packages to automatically opt in to refresh rate suppressing by small area + detection. Format of this array should be packageName:threshold and threshold value should + be between 0 to 1--> + <string-array name="config_smallAreaDetectionAllowlist" translatable="false"> + <!-- Add packages:threshold here --> + </string-array> + <!-- The list of packages to force slowJpegMode for Apps using Camera API1 --> <string-array name="config_forceSlowJpegModeList" translatable="false"> <!-- Add packages here --> @@ -6182,6 +6192,8 @@ <!-- Default value for Settings.SEARCH_PRESS_HOLD_NAV_HANDLE_ENABLED --> <bool name="config_searchPressHoldNavHandleEnabledDefault">true</bool> + <!-- Default value for Settings.ASSIST_LONG_PRESS_HOME_ENABLED for search overlay --> + <bool name="config_searchLongPressHomeEnabledDefault">true</bool> <!-- The maximum byte size of the information contained in the bundle of HotwordDetectedResult. --> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 164f713200ac..13d04e53b508 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1500,12 +1500,8 @@ please see styles_device_defaults.xml. <item name="fontFamily">google-sans-text-medium</item> <item name="textStyle">normal</item> <item name="textAllCaps">false</item> - <item name="layout_marginTop">6dp</item> - <item name="layout_marginBottom">6dp</item> - <item name="paddingStart">16dp</item> - <item name="paddingEnd">16dp</item> - <item name="paddingTop">8dp</item> - <item name="paddingBottom">8dp</item> + <item name="paddingStart">24dp</item> + <item name="paddingEnd">24dp</item> </style> <!-- @hide Tonal button for Autofill half screen dialog --> <style name="AutofillHalfSheetTonalButton" parent="AutofillHalfSheetButton"> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index ee0563b5d7cd..02209a7ff86b 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -464,6 +464,7 @@ <java-symbol type="integer" name="config_toastDefaultGravity" /> <java-symbol type="integer" name="config_triplePressOnPowerBehavior" /> <java-symbol type="integer" name="config_shortPressOnSleepBehavior" /> + <java-symbol type="bool" name="config_silenceRingerOnSleepKey" /> <java-symbol type="integer" name="config_longPressOnStemPrimaryBehavior" /> <java-symbol type="integer" name="config_shortPressOnStemPrimaryBehavior" /> <java-symbol type="string" name="config_primaryShortPressTargetActivity" /> @@ -4287,6 +4288,8 @@ <java-symbol type="array" name="config_highRefreshRateBlacklist" /> <java-symbol type="array" name="config_forceSlowJpegModeList" /> + <java-symbol type="array" name="config_smallAreaDetectionAllowlist" /> + <java-symbol type="layout" name="chooser_dialog" /> <java-symbol type="layout" name="chooser_dialog_item" /> <java-symbol type="drawable" name="chooser_dialog_background" /> @@ -4914,6 +4917,7 @@ <java-symbol type="bool" name="config_assistTouchGestureEnabledDefault" /> <java-symbol type="bool" name="config_searchPressHoldNavHandleEnabledDefault" /> + <java-symbol type="bool" name="config_searchLongPressHomeEnabledDefault" /> <java-symbol type="integer" name="config_hotwordDetectedResultMaxBundleSize" /> diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java index 0676f899674d..aaaa3c7740c5 100644 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java +++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/src/com/android/internal/os/BatteryUsageStatsPulledTest.java @@ -241,7 +241,8 @@ public class BatteryUsageStatsPulledTest { final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(new String[]{"CustomConsumer1", "CustomConsumer2"}, /* includePowerModels */ true, - /* includeProcessStats */true) + /* includeProcessStats */ true, + /* minConsumedPowerThreshold */ 0) .setDischargePercentage(20) .setDischargedPowerRange(1000, 2000) .setDischargeDurationMs(1234) @@ -325,7 +326,7 @@ public class BatteryUsageStatsPulledTest { @Test public void testLargeAtomTruncated() { final BatteryUsageStats.Builder builder = - new BatteryUsageStats.Builder(new String[0], true, false); + new BatteryUsageStats.Builder(new String[0], true, false, 0); // If not truncated, this BatteryUsageStats object would generate a proto buffer // significantly larger than 50 Kb for (int i = 0; i < 3000; i++) { diff --git a/core/tests/coretests/res/layout/viewgroup_test.xml b/core/tests/coretests/res/layout/viewgroup_test.xml index 04f4f5228b06..9b5704756044 100644 --- a/core/tests/coretests/res/layout/viewgroup_test.xml +++ b/core/tests/coretests/res/layout/viewgroup_test.xml @@ -42,8 +42,8 @@ android:id="@+id/view_translate" android:layout_width="20dp" android:layout_height="10dp" - android:translationX="10dp" - android:translationY="20dp" + android:translationX="10px" + android:translationY="20px" android:text="Hello World!" android:background="#2F00FF00" /> <FrameLayout diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java index a9234791247e..a41fb64716e2 100644 --- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java @@ -630,7 +630,7 @@ public class ActivityThreadTest { }); } - @FlakyTest(bugId = 295234586) + @FlakyTest(bugId = 298331121) @Test public void testHandleConfigurationChanged_DoesntOverrideActivityConfig() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); @@ -836,8 +836,10 @@ public class ActivityThreadTest { } private static ClientTransaction newRelaunchResumeTransaction(Activity activity) { + final Configuration currentConfig = activity.getResources().getConfiguration(); final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null, - null, 0, new MergedConfiguration(), false /* preserveWindow */); + null, 0, new MergedConfiguration(currentConfig, currentConfig), + false /* preserveWindow */); final ResumeActivityItem resumeStateRequest = ResumeActivityItem.obtain(true /* isForward */, false /* shouldSendCompatFakeFocus*/); diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java index 1ea20f162680..349fe7b36ef5 100644 --- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java +++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java @@ -53,6 +53,7 @@ public class DeviceConfigTest { private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec private static final String DEFAULT_VALUE = "test_default_value"; private static final String NAMESPACE = "namespace1"; + private static final String NAMESPACE2 = "namespace2"; private static final String KEY = "key1"; private static final String KEY2 = "key2"; private static final String KEY3 = "key3"; @@ -67,6 +68,89 @@ public class DeviceConfigTest { deleteViaContentProvider(NAMESPACE, KEY); deleteViaContentProvider(NAMESPACE, KEY2); deleteViaContentProvider(NAMESPACE, KEY3); + DeviceConfig.clearAllLocalOverrides(); + } + + /** + * Test that creating a sticky local override for a flag prevents further writes to that flag. + */ + @Test + public void testAddStickyLocalOverridePreventsWrites() { + DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE); + + String key1Value = DeviceConfig.getProperty(NAMESPACE, KEY); + assertThat(key1Value).isEqualTo(VALUE); + + DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, /* makeDefault= */ false); + key1Value = DeviceConfig.getProperty(NAMESPACE, KEY); + assertThat(key1Value).isEqualTo(VALUE); + } + + /** + * Test that when we locally override a flag, we can still write other flags. + */ + @Test + public void testAddStickyLocalOverrideDoesNotAffectOtherFlags() { + DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE); + DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE2, /* makeDefault= */ false); + String key2Value = DeviceConfig.getProperty(NAMESPACE, KEY2); + assertThat(key2Value).isEqualTo(VALUE2); + } + + /** + * Test that when we apply some overrides, they show up in the override list. + */ + @Test + public void testGetStickyLocalOverrides() { + DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, false); + DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE, false); + DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE); + DeviceConfig.setLocalOverride(NAMESPACE, KEY2, VALUE2); + + Map<String, Map<String, String>> expectedOverrides = new HashMap<>(); + Map<String, String> expectedInnerMap = new HashMap<>(); + expectedInnerMap.put(KEY, VALUE2); + expectedInnerMap.put(KEY2, VALUE); + expectedOverrides.put(NAMESPACE, expectedInnerMap); + + assertThat(DeviceConfig.getUnderlyingValuesForOverriddenFlags()) + .isEqualTo(expectedOverrides); + } + + /** + * Test that when we clear all overrides, the override list is empty. + */ + @Test + public void testClearStickyLocalOverrides() { + DeviceConfig.setLocalOverride(NAMESPACE2, KEY, VALUE); + DeviceConfig.setLocalOverride(NAMESPACE2, KEY2, VALUE2); + + DeviceConfig.clearAllLocalOverrides(); + + Map<String, Map<String, String>> overrides = + DeviceConfig.getUnderlyingValuesForOverriddenFlags(); + assertThat(overrides).isEmpty(); + } + + /** + * Test that when we clear a single override, it doesn't appear in the list. + */ + @Test + public void testClearStickyLocalOverride() { + DeviceConfig.setProperty(NAMESPACE, KEY, VALUE2, false); + DeviceConfig.setProperty(NAMESPACE2, KEY2, VALUE, false); + DeviceConfig.setLocalOverride(NAMESPACE, KEY, VALUE); + DeviceConfig.setLocalOverride(NAMESPACE2, KEY2, VALUE2); + + DeviceConfig.clearLocalOverride(NAMESPACE, KEY); + + Map<String, Map<String, String>> expectedOverrides = new HashMap<>(); + Map<String, String> expectedInnerMap = new HashMap<>(); + expectedInnerMap.put(KEY2, VALUE); + expectedOverrides.put(NAMESPACE2, expectedInnerMap); + + assertThat(DeviceConfig.getUnderlyingValuesForOverriddenFlags()) + .isEqualTo(expectedOverrides); } @Test diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java index f45db23ace76..8c93fbbc6b47 100644 --- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java @@ -16,7 +16,7 @@ package android.view; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.view.InsetsSource.ID_IME; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; @@ -81,8 +81,7 @@ public class ImeInsetsSourceConsumerTest { Insets.of(10, 10, 10, 10), rect, rect, rect, rect)); mController.calculateInsets( false, - false, - TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_RESIZE, 0, 0); mImeConsumer = mController.getImeSourceConsumer(); }); diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index b8f0d5c82eac..1568174e1955 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -16,7 +16,7 @@ package android.view; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.view.InsetsController.ANIMATION_TYPE_HIDE; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsController.ANIMATION_TYPE_RESIZE; @@ -171,8 +171,7 @@ public class InsetsControllerTest { mController.onStateChanged(state); mController.calculateInsets( false, - false, - TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_RESIZE, 0, 0); mController.onFrameChanged(new Rect(0, 0, 100, 100)); }); diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java index b06cd39d9236..906d84ec96b6 100644 --- a/core/tests/coretests/src/android/view/InsetsStateTest.java +++ b/core/tests/coretests/src/android/view/InsetsStateTest.java @@ -16,8 +16,9 @@ package android.view; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +import static android.view.InsetsSource.FLAG_FORCE_CONSUMING; import static android.view.InsetsSource.ID_IME; import static android.view.InsetsState.ISIDE_BOTTOM; import static android.view.InsetsState.ISIDE_TOP; @@ -101,7 +102,7 @@ public class InsetsStateTest { .setVisible(true); SparseIntArray typeSideMap = new SparseIntArray(); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, typeSideMap); assertEquals(Insets.of(0, 100, 0, 100), insets.getSystemWindowInsets()); assertEquals(Insets.of(0, 100, 0, 100), insets.getInsets(Type.all())); @@ -120,7 +121,7 @@ public class InsetsStateTest { .setFrame(new Rect(0, 100, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(100, insets.getStableInsetBottom()); assertEquals(Insets.of(0, 0, 0, 100), insets.getInsetsIgnoringVisibility(systemBars())); @@ -139,7 +140,7 @@ public class InsetsStateTest { .setFrame(new Rect(80, 0, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + 0, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(statusBars())); assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(navigationBars())); @@ -154,7 +155,7 @@ public class InsetsStateTest { .setFrame(new Rect(80, 0, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + 0, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(Type.statusBars())); assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(Type.navigationBars())); @@ -169,7 +170,7 @@ public class InsetsStateTest { .setFrame(new Rect(0, 200, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetBottom()); assertEquals(100, insets.getInsets(ime()).bottom); @@ -185,12 +186,12 @@ public class InsetsStateTest { .setFrame(new Rect(0, 200, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_LAYOUT_STABLE, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, null); + SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_LAYOUT_STABLE, TYPE_APPLICATION, + ACTIVITY_TYPE_UNDEFINED, null); assertEquals(100, insets.getSystemWindowInsetTop()); - insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false, + insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, SOFT_INPUT_ADJUST_NOTHING, 0, 0 /* legacySystemUiFlags */, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, null); + ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetTop()); } @@ -200,12 +201,12 @@ public class InsetsStateTest { .setFrame(new Rect(0, 0, 100, 100)) .setVisible(false); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, FLAG_FULLSCREEN, SYSTEM_UI_FLAG_LAYOUT_STABLE, - TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + SOFT_INPUT_ADJUST_NOTHING, FLAG_FULLSCREEN, SYSTEM_UI_FLAG_LAYOUT_STABLE, + TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetTop()); - insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false, + insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, SOFT_INPUT_ADJUST_NOTHING, 0, 0 /* legacySystemUiFlags */, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, null); + ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetTop()); } @@ -213,22 +214,23 @@ public class InsetsStateTest { public void testCalculateInsets_flagLayoutNoLimits() { mState.getOrCreateSource(ID_STATUS_BAR, statusBars()) .setFrame(new Rect(0, 0, 100, 100)) - .setVisible(true); + .setVisible(true) + .setFlags(FLAG_FORCE_CONSUMING); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, - 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, + 0 /* legacySystemUiFlags */, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetTop()); insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, - 0 /* legacySystemUiFlags */, TYPE_SYSTEM_ERROR, WINDOWING_MODE_UNDEFINED, null); + SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, + 0 /* legacySystemUiFlags */, TYPE_SYSTEM_ERROR, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(100, insets.getSystemWindowInsetTop()); insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, - 0 /* legacySystemUiFlags */, TYPE_WALLPAPER, WINDOWING_MODE_UNDEFINED, null); + SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, + 0 /* legacySystemUiFlags */, TYPE_WALLPAPER, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(100, insets.getSystemWindowInsetTop()); insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, - 0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_FREEFORM, null); + SOFT_INPUT_ADJUST_NOTHING, FLAG_LAYOUT_NO_LIMITS, + 0 /* legacySystemUiFlags */, TYPE_APPLICATION, ACTIVITY_TYPE_STANDARD, null); assertEquals(100, insets.getSystemWindowInsetTop()); } @@ -243,7 +245,7 @@ public class InsetsStateTest { .setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + new Rect(0, 0, 100, 400), TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 300, 0, 0), visibleInsets); } @@ -255,7 +257,7 @@ public class InsetsStateTest { .setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 150, 400), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + new Rect(0, 0, 150, 400), TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 300, 0, 0), visibleInsets); } @@ -269,7 +271,7 @@ public class InsetsStateTest { .setFrame(new Rect(80, 0, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + 0, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(statusBars())); assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(navigationBars())); @@ -284,7 +286,7 @@ public class InsetsStateTest { .setFrame(new Rect(80, 0, 100, 300)) .setVisible(true); WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, - false, 0, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + 0, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(Insets.of(0, 100, 20, 0), insets.getSystemWindowInsets()); assertEquals(Insets.of(0, 100, 0, 0), insets.getInsets(statusBars())); assertEquals(Insets.of(0, 0, 20, 0), insets.getInsets(navigationBars())); @@ -292,11 +294,11 @@ public class InsetsStateTest { @Test public void testCalculateInsets_emptyIme() { - WindowInsets insets1 = mState.calculateInsets(new Rect(), null, false, false, - SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + WindowInsets insets1 = mState.calculateInsets(new Rect(), null, false, + SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); mState.getOrCreateSource(ID_IME, ime()); - WindowInsets insets2 = mState.calculateInsets(new Rect(), null, false, false, - SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + WindowInsets insets2 = mState.calculateInsets(new Rect(), null, false, + SOFT_INPUT_ADJUST_NOTHING, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(Insets.NONE, insets1.getInsets(ime())); assertEquals(Insets.NONE, insets2.getInsets(ime())); assertEquals(insets1, insets2); @@ -311,8 +313,8 @@ public class InsetsStateTest { .setFrame(new Rect(0, 200, 100, 300)) .setVisible(true); mState.removeSource(ID_IME); - WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, false, - SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, null); + WindowInsets insets = mState.calculateInsets(new Rect(0, 0, 100, 300), null, false, + SOFT_INPUT_ADJUST_RESIZE, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, null); assertEquals(0, insets.getSystemWindowInsetBottom()); } @@ -527,7 +529,7 @@ public class InsetsStateTest { .setFrame(new Rect(0, 100, 100, 300)) .setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + new Rect(0, 0, 100, 300), TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_PAN, 0 /* windowFlags */); assertEquals(Insets.of(0, 100, 0, 100), visibleInsets); } @@ -546,7 +548,7 @@ public class InsetsStateTest { .setFrame(new Rect(0, 100, 100, 300)) .setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + new Rect(0, 0, 100, 300), TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_NOTHING, 0 /* windowFlags */); assertEquals(Insets.of(0, 100, 0, 0), visibleInsets); } @@ -565,7 +567,7 @@ public class InsetsStateTest { .setFrame(new Rect(0, 100, 100, 300)) .setVisible(true); Insets visibleInsets = mState.calculateVisibleInsets( - new Rect(0, 0, 100, 300), TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + new Rect(0, 0, 100, 300), TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, SOFT_INPUT_ADJUST_PAN, FLAG_LAYOUT_NO_LIMITS); assertEquals(Insets.NONE, visibleInsets); } @@ -599,8 +601,8 @@ public class InsetsStateTest { new Rect(0, 0, 1, 2), new Rect(197, 296, 200, 300), new Rect(197, 296, 200, 300))); - DisplayCutout cutout = mState.calculateInsets(new Rect(1, 1, 199, 300), null, false, false, - SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, + DisplayCutout cutout = mState.calculateInsets(new Rect(1, 1, 199, 300), null, false, + SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, ACTIVITY_TYPE_UNDEFINED, new SparseIntArray()).getDisplayCutout(); assertEquals(0, cutout.getSafeInsetLeft()); assertEquals(1, cutout.getSafeInsetTop()); @@ -625,8 +627,8 @@ public class InsetsStateTest { new RoundedCorner(POSITION_BOTTOM_RIGHT, 20, 180, 380), new RoundedCorner(POSITION_BOTTOM_LEFT, 20, 20, 380))); WindowInsets windowInsets = mState.calculateInsets(new Rect(1, 2, 197, 396), null, false, - false, SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, new SparseIntArray()); + SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, + ACTIVITY_TYPE_UNDEFINED, new SparseIntArray()); assertEquals(new RoundedCorner(POSITION_TOP_LEFT, 10, 9, 8), windowInsets.getRoundedCorner(POSITION_TOP_LEFT)); assertEquals(new RoundedCorner(POSITION_TOP_RIGHT, 10, 189, 8), @@ -642,8 +644,8 @@ public class InsetsStateTest { mState.setDisplayFrame(new Rect(0, 0, 200, 400)); mState.setDisplayShape(DisplayShape.createDefaultDisplayShape(200, 400, false)); WindowInsets windowInsets = mState.calculateInsets(new Rect(10, 20, 200, 400), null, false, - false, SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, - WINDOWING_MODE_UNDEFINED, new SparseIntArray()); + SOFT_INPUT_ADJUST_UNSPECIFIED, 0, 0, TYPE_APPLICATION, + ACTIVITY_TYPE_UNDEFINED, new SparseIntArray()); final DisplayShape expect = DisplayShape.createDefaultDisplayShape(200, 400, false).setOffset(-10, -20); diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java index 274c25a17f58..94298dcd2c74 100644 --- a/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java +++ b/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java @@ -92,18 +92,18 @@ public class ParsedVibrationTest { } @Test - public void testGetVibrationEffectListForTesting() { + public void testGetVibrationEffects() { ParsedVibration parsedVibration = new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3)); - assertThat(parsedVibration.getVibrationEffectListForTesting()) + assertThat(parsedVibration.getVibrationEffects()) .containsExactly(mEffect1, mEffect2, mEffect3) .inOrder(); parsedVibration = new ParsedVibration(List.of(mEffect1)); - assertThat(parsedVibration.getVibrationEffectListForTesting()).containsExactly(mEffect1); + assertThat(parsedVibration.getVibrationEffects()).containsExactly(mEffect1); parsedVibration = new ParsedVibration(List.of()); - assertThat(parsedVibration.getVibrationEffectListForTesting()).isEmpty(); + assertThat(parsedVibration.getVibrationEffects()).isEmpty(); } private Subject assertThatResolution( diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java index d73b5cb5713b..2814a5f5366c 100644 --- a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java +++ b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java @@ -363,8 +363,7 @@ public class VibrationEffectXmlSerializationTest { private void assertParseDocumentSucceeds(String xml, int flags, VibrationEffect... effects) throws Exception { - assertThat(parseDocument(xml, flags).getVibrationEffectListForTesting()) - .containsExactly(effects); + assertThat(parseDocument(xml, flags).getVibrationEffects()).containsExactly(effects); } /** @@ -381,8 +380,7 @@ public class VibrationEffectXmlSerializationTest { String tagName = parser.getName(); assertThat(Set.of("vibration", "vibration-select")).contains(tagName); - assertThat(parseElement(parser, flags).getVibrationEffectListForTesting()) - .containsExactly(effects); + assertThat(parseElement(parser, flags).getVibrationEffects()).containsExactly(effects); assertThat(parser.getEventType()).isEqualTo(XmlPullParser.END_TAG); assertThat(parser.getName()).isEqualTo(tagName); } diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 9fb627fcc501..4c4e8fa9c088 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -1475,7 +1475,10 @@ public class Typeface { String locale = SystemProperties.get("persist.sys.locale", "en-US"); String script = ULocale.addLikelySubtags(ULocale.forLanguageTag(locale)).getScript(); - FontConfig config = SystemFonts.getSystemPreinstalledFontConfig(); + // The feature flag cannot be referred from Zygote. Use legacy fonts.xml for preloading font + // files. + // TODO(nona): Use new XML file once the feature is fully launched. + FontConfig config = SystemFonts.getSystemPreinstalledFontConfigFromLegacyXml(); for (int i = 0; i < config.getFontFamilies().size(); ++i) { FontConfig.FontFamily family = config.getFontFamilies().get(i); if (!family.getLocaleList().isEmpty()) { diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java index 36bfb98e726b..9810022abfed 100644 --- a/graphics/java/android/graphics/fonts/SystemFonts.java +++ b/graphics/java/android/graphics/fonts/SystemFonts.java @@ -48,6 +48,8 @@ public final class SystemFonts { private static final String TAG = "SystemFonts"; private static final String FONTS_XML = "/system/etc/font_fallback.xml"; + private static final String LEGACY_FONTS_XML = "/system/etc/fonts.xml"; + /** @hide */ public static final String SYSTEM_FONT_DIR = "/system/fonts/"; private static final String OEM_XML = "/product/etc/fonts_customization.xml"; @@ -230,7 +232,13 @@ public final class SystemFonts { long lastModifiedDate, int configVersion ) { - return getSystemFontConfigInternal(FONTS_XML, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, + final String fontsXml; + if (com.android.text.flags.Flags.deprecateFontsXml()) { + fontsXml = FONTS_XML; + } else { + fontsXml = LEGACY_FONTS_XML; + } + return getSystemFontConfigInternal(fontsXml, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, updatableFontMap, lastModifiedDate, configVersion); } @@ -255,10 +263,24 @@ public final class SystemFonts { * @hide */ public static @NonNull FontConfig getSystemPreinstalledFontConfig() { - return getSystemFontConfigInternal(FONTS_XML, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, null, + final String fontsXml; + if (com.android.text.flags.Flags.deprecateFontsXml()) { + fontsXml = FONTS_XML; + } else { + fontsXml = LEGACY_FONTS_XML; + } + return getSystemFontConfigInternal(fontsXml, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, null, 0, 0); } + /** + * @hide + */ + public static @NonNull FontConfig getSystemPreinstalledFontConfigFromLegacyXml() { + return getSystemFontConfigInternal(LEGACY_FONTS_XML, SYSTEM_FONT_DIR, OEM_XML, OEM_FONT_DIR, + null, 0, 0); + } + /* package */ static @NonNull FontConfig getSystemFontConfigInternal( @NonNull String fontsXml, @NonNull String systemFontDir, diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java index 55eabb039c01..c3d8f9a99d79 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java @@ -16,12 +16,14 @@ package androidx.window.extensions; +import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.Application; import android.content.Context; import android.window.TaskFragmentOrganizer; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.window.common.DeviceStateManagerFoldingFeatureProducer; import androidx.window.common.RawFoldingFeatureProducer; import androidx.window.extensions.area.WindowAreaComponent; @@ -111,9 +113,13 @@ public class WindowExtensionsImpl implements WindowExtensions { * {@link WindowExtensions#getWindowLayoutComponent()}. * @return {@link ActivityEmbeddingComponent} OEM implementation. */ - @NonNull + @Nullable public ActivityEmbeddingComponent getActivityEmbeddingComponent() { if (mSplitController == null) { + if (!ActivityTaskManager.supportsMultiWindow(getApplication())) { + // Disable AE for device that doesn't support multi window. + return null; + } synchronized (mLock) { if (mSplitController == null) { mSplitController = new SplitController( diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index ccf95527efea..e03e1ecd6015 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -319,13 +319,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { return features; } + // We will transform the feature bounds to the Activity window, so using the rotation + // from the same source (WindowConfiguration) to make sure they are synchronized. + final int rotation = windowConfiguration.getDisplayRotation(); + for (CommonFoldingFeature baseFeature : storedFeatures) { Integer state = convertToExtensionState(baseFeature.getState()); if (state == null) { continue; } Rect featureRect = baseFeature.getRect(); - rotateRectToDisplayRotation(displayId, featureRect); + rotateRectToDisplayRotation(displayId, rotation, featureRect); transformToWindowSpaceRect(windowConfiguration, featureRect); if (isZero(featureRect)) { diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java index 5bfb0ebdcaa8..15a329bd9509 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java @@ -120,10 +120,12 @@ class SampleSidecarImpl extends StubSidecar { } List<SidecarDisplayFeature> features = new ArrayList<>(); + final int rotation = activity.getResources().getConfiguration().windowConfiguration + .getDisplayRotation(); for (CommonFoldingFeature baseFeature : mStoredFeatures) { SidecarDisplayFeature feature = new SidecarDisplayFeature(); Rect featureRect = baseFeature.getRect(); - rotateRectToDisplayRotation(displayId, featureRect); + rotateRectToDisplayRotation(displayId, rotation, featureRect); transformToWindowSpaceRect(activity, featureRect); feature.setRect(featureRect); feature.setType(baseFeature.getType()); diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java index 9e2611f392a3..57f83088b2ba 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java @@ -16,8 +16,6 @@ package androidx.window.util; -import static android.view.Surface.ROTATION_0; -import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; @@ -25,8 +23,8 @@ import android.app.WindowConfiguration; import android.content.Context; import android.graphics.Rect; import android.hardware.display.DisplayManagerGlobal; +import android.util.RotationUtils; import android.view.DisplayInfo; -import android.view.Surface; import android.view.WindowManager; import androidx.annotation.NonNull; @@ -45,10 +43,9 @@ public final class ExtensionHelper { * Rotates the input rectangle specified in default display orientation to the current display * rotation. */ - public static void rotateRectToDisplayRotation(int displayId, Rect inOutRect) { + public static void rotateRectToDisplayRotation(int displayId, int rotation, Rect inOutRect) { DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance(); DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId); - int rotation = displayInfo.rotation; boolean isSideRotation = rotation == ROTATION_90 || rotation == ROTATION_270; int displayWidth = isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth; @@ -56,35 +53,7 @@ public final class ExtensionHelper { inOutRect.intersect(0, 0, displayWidth, displayHeight); - rotateBounds(inOutRect, displayWidth, displayHeight, rotation); - } - - /** - * Rotates the input rectangle within parent bounds for a given delta. - */ - private static void rotateBounds(Rect inOutRect, int parentWidth, int parentHeight, - @Surface.Rotation int delta) { - int origLeft = inOutRect.left; - switch (delta) { - case ROTATION_0: - return; - case ROTATION_90: - inOutRect.left = inOutRect.top; - inOutRect.top = parentWidth - inOutRect.right; - inOutRect.right = inOutRect.bottom; - inOutRect.bottom = parentWidth - origLeft; - return; - case ROTATION_180: - inOutRect.left = parentWidth - inOutRect.right; - inOutRect.right = parentWidth - origLeft; - return; - case ROTATION_270: - inOutRect.left = parentHeight - inOutRect.bottom; - inOutRect.bottom = inOutRect.right; - inOutRect.right = parentHeight - inOutRect.top; - inOutRect.top = origLeft; - return; - } + RotationUtils.rotateBounds(inOutRect, displayWidth, displayHeight, rotation); } /** Transforms rectangle from absolute coordinate space to the window coordinate space. */ diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java index d189ae2cf72e..45564cb46c67 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java @@ -16,8 +16,11 @@ package androidx.window.extensions; +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + import static com.google.common.truth.Truth.assertThat; +import android.app.ActivityTaskManager; import android.platform.test.annotations.Presubmit; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -52,7 +55,11 @@ public class WindowExtensionsTest { @Test public void testGetActivityEmbeddingComponent() { - assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull(); + if (ActivityTaskManager.supportsMultiWindow(getInstrumentation().getContext())) { + assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull(); + } else { + assertThat(mExtensions.getActivityEmbeddingComponent()).isNull(); + } } @Test diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml index 1164d3778826..4f763425b601 100644 --- a/libs/WindowManager/Shell/res/values-af/strings.xml +++ b/libs/WindowManager/Shell/res/values-af/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Het dit"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen onlangse borrels nie"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Onlangse borrels en borrels wat toegemaak is, sal hier verskyn"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Beheer borrels enige tyd"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tik hier om te bestuur watter apps en gesprekke in borrels kan verskyn"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Borrel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Bestuur"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Borrel is toegemaak."</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index ffed367926e1..1e5f5f136315 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ገባኝ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ምንም የቅርብ ጊዜ አረፋዎች የሉም"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"የቅርብ ጊዜ አረፋዎች እና የተሰናበቱ አረፋዎች እዚህ ብቅ ይላሉ"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"በማንኛውም ጊዜ ዓረፋዎችን ይቆጣጠሩ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"የትኛዎቹ መተግበሪያዎች እና ውይይቶች ዓረፋ መፍጠር እንደሚችሉ ለማስተዳደር እዚህ ጋር መታ ያድርጉ"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string> diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml index 4e9b76bc4948..9c52608a8d23 100644 --- a/libs/WindowManager/Shell/res/values-ar/strings.xml +++ b/libs/WindowManager/Shell/res/values-ar/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"حسنًا"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ليس هناك فقاعات محادثات"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ستظهر هنا أحدث فقاعات المحادثات وفقاعات المحادثات التي تم إغلاقها."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"التحكّم في إظهار الفقاعات في أي وقت"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"انقر هنا للتحكّم في إظهار فقاعات التطبيقات والمحادثات التي تريدها."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string> diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml index a583f349d1f1..e880b8744f40 100644 --- a/libs/WindowManager/Shell/res/values-as/strings.xml +++ b/libs/WindowManager/Shell/res/values-as/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"বুজি পালোঁ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"কোনো শেহতীয়া bubbles নাই"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"শেহতীয়া bubbles আৰু অগ্ৰাহ্য কৰা bubbles ইয়াত প্ৰদর্শিত হ\'ব"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"যিকোনো সময়তে বাবল নিয়ন্ত্ৰণ কৰক"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"কোনবোৰ এপ্ আৰু বাৰ্তালাপ বাবল হ’ব পাৰে সেয়া পৰিচালনা কৰিবলৈ ইয়াত টিপক"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string> diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml index fb09258aef26..6e746fb761f0 100644 --- a/libs/WindowManager/Shell/res/values-az/strings.xml +++ b/libs/WindowManager/Shell/res/values-az/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Anladım"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Yumrucuqlar yoxdur"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Son yumrucuqlar və buraxılmış yumrucuqlar burada görünəcək"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Yumrucuqları idarə edin"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Bura toxunaraq yumrucuq göstərəcək tətbiq və söhbətləri idarə edin"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Qabarcıq"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"İdarə edin"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Qabarcıqdan imtina edilib."</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index a9ba12e6508a..3be326907cd2 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Važi"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovde se prikazuju nedavni i odbačeni oblačići"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolišite oblačiće u svakom trenutku"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovde i odredite koje aplikacije i konverzacije mogu da imaju oblačić"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljajte"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml index eef363be387b..85ae1c10617c 100644 --- a/libs/WindowManager/Shell/res/values-be/strings.xml +++ b/libs/WindowManager/Shell/res/values-be/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Зразумела"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Няма нядаўніх усплывальных апавяшчэнняў"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Нядаўнія і адхіленыя ўсплывальныя апавяшчэнні будуць паказаны тут"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Кіруйце наладамі ўсплывальных апавяшчэнняў у любы час"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Каб кіраваць усплывальнымі апавяшчэннямі для праграм і размоў, націсніце тут"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string> diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml index 281bd9d5f37d..640fb2e0ef92 100644 --- a/libs/WindowManager/Shell/res/values-bg/strings.xml +++ b/libs/WindowManager/Shell/res/values-bg/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Разбрах"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Няма скорошни балончета"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Скорошните и отхвърлените балончета ще се показват тук"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Управление на балончетата по всяко време"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Докоснете тук, за да управл. кои прил. и разговори могат да показват балончета"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string> diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml index 3dae948f96ea..e7c8886a99be 100644 --- a/libs/WindowManager/Shell/res/values-bn/strings.xml +++ b/libs/WindowManager/Shell/res/values-bn/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"বুঝেছি"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"কোনও সাম্প্রতিক বাবল নেই"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"সাম্প্রতিক ও বাতিল করা বাবল এখানে দেখা যাবে"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"যেকোনও সময় বাবল নিয়ন্ত্রণ করুন"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"কোন অ্যাপ ও কথোপকথনের জন্য বাবলের সুবিধা চান তা ম্যানেজ করতে এখানে ট্যাপ করুন"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string> diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml index 8b7eb6143fb3..1335f8d897be 100644 --- a/libs/WindowManager/Shell/res/values-bs/strings.xml +++ b/libs/WindowManager/Shell/res/values-bs/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Razumijem"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nedavni i odbačeni oblačići će se pojaviti ovdje"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljajte oblačićima u svakom trenutku"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovdje da upravljate time koje aplikacije i razgovori mogu imati oblačić"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić je odbačen."</string> diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml index 2250f9d7132a..22fc21c64e09 100644 --- a/libs/WindowManager/Shell/res/values-ca/strings.xml +++ b/libs/WindowManager/Shell/res/values-ca/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entesos"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hi ha bombolles recents"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bombolles recents i les ignorades es mostraran aquí"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla les bombolles en qualsevol moment"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca aquí per gestionar quines aplicacions i converses poden fer servir bombolles"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bombolla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestiona"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"La bombolla s\'ha ignorat."</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index ebee2c181d58..a85fa7c9435d 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Žádné nedávné bubliny"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Zde se budou zobrazovat nedávné bubliny a zavřené bubliny"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Nastavení bublin můžete kdykoli upravit"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Klepnutím sem lze spravovat, které aplikace a konverzace mohou vytvářet bubliny"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string> diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml index 4e4624371ab9..cd621f802d91 100644 --- a/libs/WindowManager/Shell/res/values-da/strings.xml +++ b/libs/WindowManager/Shell/res/values-da/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ingen seneste bobler"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nye bobler og afviste bobler vises her"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Administrer bobler når som helst"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tryk her for at administrere, hvilke apps og samtaler der kan vises i bobler"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen blev lukket."</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 1d5182a14f97..366fdefc3013 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Keine kürzlich geschlossenen Bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Hier werden aktuelle und geschlossene Bubbles angezeigt"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bubble-Einstellungen festlegen"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tippe hier, um zu verwalten, welche Apps und Unterhaltungen als Bubble angezeigt werden können"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Verwalten"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble verworfen."</string> diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml index 34a6a071286d..a449b9f3c665 100644 --- a/libs/WindowManager/Shell/res/values-el/strings.xml +++ b/libs/WindowManager/Shell/res/values-el/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Το κατάλαβα"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Δεν υπάρχουν πρόσφατα συννεφάκια"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Τα πρόσφατα συννεφάκια και τα συννεφάκια που παραβλέψατε θα εμφανίζονται εδώ."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ελέγξτε τα συννεφάκια ανά πάσα στιγμή."</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Πατήστε εδώ για τη διαχείριση εφαρμογών και συζητήσεων που προβάλλουν συννεφάκια"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml index c6e1c5f1a5a3..c7dd3882734b 100644 --- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml index e536930ec925..99da073cb2c2 100644 --- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Got it"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles anytime"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml index c6e1c5f1a5a3..c7dd3882734b 100644 --- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml index c6e1c5f1a5a3..c7dd3882734b 100644 --- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles at any time"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml index 83631eb3ff41..cc19579c1216 100644 --- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml +++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Got it"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No recent bubbles"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recent bubbles and dismissed bubbles will appear here"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Control bubbles anytime"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tap here to manage which apps and conversations can bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Manage"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubble dismissed."</string> diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml index c0dfeefef0c0..80d10f26e4e9 100644 --- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml +++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hay burbujas recientes"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Las burbujas recientes y las que se descartaron aparecerán aquí"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla las burbujas"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Presiona para administrar las apps y conversaciones que pueden mostrar burbujas"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Cuadro"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Se descartó el cuadro."</string> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index 0e66c9bbb819..13dfce03b775 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"No hay burbujas recientes"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Las burbujas recientes y las cerradas aparecerán aquí"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controla las burbujas cuando quieras"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca aquí para gestionar qué aplicaciones y conversaciones pueden usar burbujas"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 201f336b6a96..269968f48c77 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Selge"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hiljutisi mulle pole"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Siin kuvatakse hiljutised ja suletud mullid."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Juhtige mulle igal ajal"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Puudutage siin, et hallata, milliseid rakendusi ja vestlusi saab mullina kuvada"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Mull"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Halda"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Mullist loobuti."</string> diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml index 84439546f72e..b4a8d57abc94 100644 --- a/libs/WindowManager/Shell/res/values-eu/strings.xml +++ b/libs/WindowManager/Shell/res/values-eu/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ados"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ez dago azkenaldiko burbuilarik"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Azken burbuilak eta baztertutakoak agertuko dira hemen"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolatu burbuilak edonoiz"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Sakatu hau burbuiletan zein aplikazio eta elkarrizketa ager daitezkeen kudeatzeko"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuila"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kudeatu"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Baztertu da globoa."</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 4f546e7a2c1b..434bfe11db4e 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"متوجهام"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"هیچ حبابک جدیدی وجود ندارد"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابکهای اخیر و حبابکهای ردشده اینجا ظاهر خواهند شد"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کنترل حبابکها در هرزمانی"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامهها و مکالمهها حباب داشته باشند، ضربه بزنید"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"حباب"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"مدیریت"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"حبابک رد شد."</string> diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml index d8a18a033616..a04ef1252aa8 100644 --- a/libs/WindowManager/Shell/res/values-fi/strings.xml +++ b/libs/WindowManager/Shell/res/values-fi/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Okei"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ei viimeaikaisia kuplia"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Viimeaikaiset ja äskettäin ohitetut kuplat näkyvät täällä"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Muuta kuplien asetuksia milloin tahansa"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Valitse napauttamalla tästä, mitkä sovellukset ja keskustelut voivat kuplia"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Kupla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Ylläpidä"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Kupla ohitettu."</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index b2077f9b05d9..fbc619144f71 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et les bulles ignorées s\'afficheront ici"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Gérez les bulles en tout temps"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Touchez ici pour gérer les applis et les conversations à inclure aux bulles"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index b1b83133584d..e1fe2917a729 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et ignorées s\'afficheront ici"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Contrôlez les bulles à tout moment"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Appuyez ici pour gérer les applis et conversations s\'affichant dans des bulles"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string> diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml index fd90e31dc6c4..485a89502c86 100644 --- a/libs/WindowManager/Shell/res/values-gl/strings.xml +++ b/libs/WindowManager/Shell/res/values-gl/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Entendido"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Non hai burbullas recentes"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"As burbullas recentes e ignoradas aparecerán aquí."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controlar as burbullas"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toca para xestionar as aplicacións e conversas que poden aparecer en burbullas"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Xestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ignorouse a burbulla."</string> diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml index d7e34fb2888b..365faef85ff6 100644 --- a/libs/WindowManager/Shell/res/values-gu/strings.xml +++ b/libs/WindowManager/Shell/res/values-gu/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"સમજાઈ ગયું"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"તાજેતરના કોઈ બબલ નથી"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"એકદમ નવા બબલ અને છોડી દીધેલા બબલ અહીં દેખાશે"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"બબલને કોઈપણ સમયે નિયંત્રિત કરે છે"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"કઈ ઍપ અને વાતચીતોને બબલ કરવા માગો છો તે મેનેજ કરવા માટે, અહીં ટૅપ કરો"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index 679ea65bb882..76579d10b695 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -76,19 +76,14 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ठीक है"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हाल ही के कोई बबल्स नहीं हैं"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हाल ही के बबल्स और हटाए गए बबल्स यहां दिखेंगे"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"जब चाहें, बबल्स की सुविधा को कंट्रोल करें"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"किसी ऐप्लिकेशन और बातचीत के लिए बबल की सुविधा को मैनेज करने के लिए यहां टैप करें"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string> - <!-- no translation found for restart_button_description (4564728020654658478) --> - <skip /> - <!-- no translation found for user_aspect_ratio_settings_button_hint (734835849600713016) --> - <skip /> - <!-- no translation found for user_aspect_ratio_settings_button_description (4315566801697411684) --> - <skip /> + <string name="restart_button_description" msgid="4564728020654658478">"बेहतर व्यू पाने के लिए, टैप करके ऐप्लिकेशन को रीस्टार्ट करें"</string> + <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिंग में जाकर इस ऐप्लिकेशन का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string> + <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 88aa1b2b645d..de071f1b959d 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Shvaćam"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nema nedavnih oblačića"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Ovdje će se prikazivati nedavni i odbačeni oblačići"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljanje oblačićima u svakom trenutku"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dodirnite ovdje da biste odredili koje aplikacije i razgovori mogu imati oblačić"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string> diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml index 5a88bc4753a9..b5631bbf0152 100644 --- a/libs/WindowManager/Shell/res/values-hu/strings.xml +++ b/libs/WindowManager/Shell/res/values-hu/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Értem"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nincsenek buborékok a közelmúltból"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"A legutóbbi és az elvetett buborékok itt jelennek majd meg"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Buborékok vezérlése bármikor"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ide koppintva jeleníthetők meg az alkalmazások és a beszélgetések buborékként"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Buborék"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kezelés"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Buborék elvetve."</string> diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml index 54b1213ad216..2d5d371df41e 100644 --- a/libs/WindowManager/Shell/res/values-hy/strings.xml +++ b/libs/WindowManager/Shell/res/values-hy/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Եղավ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ամպիկներ չկան"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Այստեղ կցուցադրվեն վերջերս օգտագործված և փակված ամպիկները, որոնք կկարողանաք հեշտությամբ վերաբացել"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ամպիկների կարգավորումներ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Հպեք այստեղ՝ ընտրելու, թե որ հավելվածների և զրույցների համար ամպիկներ ցուցադրել"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 32167b30946b..90b1f152d035 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Oke"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Tidak ada balon baru-baru ini"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Balon yang baru dipakai dan balon yang telah ditutup akan muncul di sini"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrol balon kapan saja"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ketuk di sini untuk mengelola balon aplikasi dan percakapan"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Kelola"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon ditutup."</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 1304ae149425..813f9e6f4021 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ég skil"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Engar nýlegar blöðrur"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nýlegar blöðrur og blöðrur sem þú hefur lokað birtast hér"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Hægt er að stjórna blöðrum hvenær sem er"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ýttu hér til að stjórna því hvaða forrit og samtöl mega nota blöðrur."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string> diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml index dceac5c2722a..8918821a8f27 100644 --- a/libs/WindowManager/Shell/res/values-it/strings.xml +++ b/libs/WindowManager/Shell/res/values-it/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nessuna bolla recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Le bolle recenti e ignorate appariranno qui"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Gestisci le bolle in qualsiasi momento"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tocca qui per gestire le app e le conversazioni per cui mostrare le bolle"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Fumetto"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestisci"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Fumetto ignorato."</string> diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml index 7cde568b9123..4d7a0936a3e0 100644 --- a/libs/WindowManager/Shell/res/values-iw/strings.xml +++ b/libs/WindowManager/Shell/res/values-iw/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"הבנתי"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"אין בועות מהזמן האחרון"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"בועות אחרונות ובועות שנסגרו יופיעו כאן"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"שליטה בבועות בכל זמן"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"אפשר להקיש כאן כדי לקבוע אילו אפליקציות ושיחות יוכלו להופיע בבועות"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 3b3c4e493e4c..96683590d097 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近閉じたバブルはありません"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近表示されたバブルや閉じたバブルが、ここに表示されます"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"バブルはいつでも管理可能"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"バブルで表示するアプリや会話を管理するには、ここをタップします"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string> diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml index 3c32e0e6fe8d..a949a18fd449 100644 --- a/libs/WindowManager/Shell/res/values-ka/strings.xml +++ b/libs/WindowManager/Shell/res/values-ka/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"გასაგებია"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ბოლო დროს გამოყენებული ბუშტები არ არის"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"აქ გამოჩნდება ბოლოდროინდელი ბუშტები და უარყოფილი ბუშტები"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ამოხტომის გაკონტროლება ნებისმიერ დროს"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"აქ შეეხეთ იმის სამართავად, თუ რომელი აპები და საუბრები ამოხტეს"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index ac5f4bf60309..cbc924907cac 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түсінікті"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Жақындағы қалқыма хабарлар жоқ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Соңғы және жабылған қалқыма хабарлар осы жерде көрсетіледі."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Қалқыма хабарларды кез келген уақытта басқарыңыз"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Қалқыма хабарда көрсетілетін қолданбалар мен әңгімелерді реттеу үшін осы жерді түртіңіз."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string> diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml index adb229ab8039..3e36113995d9 100644 --- a/libs/WindowManager/Shell/res/values-km/strings.xml +++ b/libs/WindowManager/Shell/res/values-km/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"យល់ហើយ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"មិនមានពពុះថ្មីៗទេ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ពពុះថ្មីៗ និងពពុះដែលបានបិទនឹងបង្ហាញនៅទីនេះ"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"គ្រប់គ្រងផ្ទាំងអណ្ដែតនៅពេលណាក៏បាន"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ចុចត្រង់នេះ ដើម្បីគ្រប់គ្រងកម្មវិធី និងការសន្ទនាដែលអាចបង្ហាញជាផ្ទាំងអណ្ដែត"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោលសារលេចឡើង។"</string> diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml index 33c50e7530a7..5e0dad8255b4 100644 --- a/libs/WindowManager/Shell/res/values-kn/strings.xml +++ b/libs/WindowManager/Shell/res/values-kn/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ಅರ್ಥವಾಯಿತು"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಇಲ್ಲ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ಇತ್ತೀಚಿನ ಬಬಲ್ಸ್ ಮತ್ತು ವಜಾಗೊಳಿಸಿದ ಬಬಲ್ಸ್ ಇಲ್ಲಿ ಗೋಚರಿಸುತ್ತವೆ"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಬಬಲ್ಸ್ ಅನ್ನು ನಿಯಂತ್ರಿಸಿ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ಯಾವ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಸಂಭಾಷಣೆಗಳನ್ನು ಬಬಲ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ನಿರ್ವಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index dc76769618aa..f1b34556954e 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"확인"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"최근 대화창 없음"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"최근 대화창과 내가 닫은 대화창이 여기에 표시됩니다."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"언제든지 대화창을 제어하세요"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"대화창을 만들 수 있는 앱과 대화를 관리하려면 여기를 탭하세요."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index b1c0a6712093..200359aded72 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Түшүндүм"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Азырынча эч нерсе жок"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Акыркы жана жабылган калкып чыкма билдирмелер ушул жерде көрүнөт"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Калкып чыкма билдирмелерди каалаган убакта көзөмөлдөңүз"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Калкып чыкма билдирме түрүндө көрүнө турган колдонмолор менен маектерди тандоо үчүн бул жерди таптаңыз"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string> diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml index 0b5da776df17..43835d5afa67 100644 --- a/libs/WindowManager/Shell/res/values-lo/strings.xml +++ b/libs/WindowManager/Shell/res/values-lo/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ເຂົ້າໃຈແລ້ວ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ບໍ່ມີຟອງຫຼ້າສຸດ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ຟອງຫຼ້າສຸດ ແລະ ຟອງທີ່ປິດໄປຈະປາກົດຢູ່ບ່ອນນີ້"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ຄວບຄຸມຟອງໄດ້ທຸກເວລາ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ແຕະບ່ອນນີ້ເພື່ອຈັດການແອັບ ແລະ ການສົນທະນາທີ່ສາມາດສະແດງເປັນແບບຟອງໄດ້"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ຟອງ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ຈັດການ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ປິດ Bubble ໄສ້ແລ້ວ."</string> diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml index ecec41a10d36..0c6cc58aa1ec 100644 --- a/libs/WindowManager/Shell/res/values-lt/strings.xml +++ b/libs/WindowManager/Shell/res/values-lt/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Supratau"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nėra naujausių burbulų"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Naujausi ir atsisakyti burbulai bus rodomi čia"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bet kada valdyti burbulus"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Palietę čia valdykite, kurie pokalbiai ir programos gali būti rodomi burbuluose"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Debesėlis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Tvarkyti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Debesėlio atsisakyta."</string> diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml index d3a15bda9fd2..f86e937edd33 100644 --- a/libs/WindowManager/Shell/res/values-lv/strings.xml +++ b/libs/WindowManager/Shell/res/values-lv/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Labi"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nav nesen aizvērtu burbuļu"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Šeit būs redzami nesen rādītie burbuļi un aizvērtie burbuļi"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Pārvaldīt burbuļus jebkurā laikā"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Pieskarieties šeit, lai pārvaldītu, kuras lietotnes un sarunas var rādīt burbulī"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Burbulis"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pārvaldīt"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbulis ir noraidīts."</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 008cff29ee9e..49e850fac1c0 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Сфатив"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема неодамнешни балончиња"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Неодамнешните и отфрлените балончиња ќе се појавуваат тука"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контролирајте ги балончињата во секое време"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Допрете тука за да одредите на кои апл. и разговори може да се појават балончиња"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string> diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml index 4e2f339b3989..fbb5514e4648 100644 --- a/libs/WindowManager/Shell/res/values-ml/strings.xml +++ b/libs/WindowManager/Shell/res/values-ml/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"മനസ്സിലായി"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"അടുത്തിടെയുള്ള ബബിളുകൾ ഒന്നുമില്ല"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"അടുത്തിടെയുള്ള ബബിളുകൾ, ഡിസ്മിസ് ചെയ്ത ബബിളുകൾ എന്നിവ ഇവിടെ ദൃശ്യമാവും"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ബബിളുകൾ ഏതുസമയത്തും നിയന്ത്രിക്കുക"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ഏതൊക്കെ ആപ്പുകളും സംഭാഷണങ്ങളും ബബിൾ ചെയ്യാനാകുമെന്നത് മാനേജ് ചെയ്യാൻ ഇവിടെ ടാപ്പ് ചെയ്യുക"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string> diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml index c2081cfb69d7..8274f4456c57 100644 --- a/libs/WindowManager/Shell/res/values-mn/strings.xml +++ b/libs/WindowManager/Shell/res/values-mn/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ойлголоо"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Саяхны бөмбөлөг алга байна"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Саяхны бөмбөлгүүд болон үл хэрэгссэн бөмбөлгүүд энд харагдана"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Бөмбөлгүүдийг хүссэн үедээ хянах"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ямар апп болон харилцан ярианууд бөмбөлгөөр харагдахыг энд удирдана уу"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string> diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml index f563ec63c8ce..c1f3e123ac41 100644 --- a/libs/WindowManager/Shell/res/values-mr/strings.xml +++ b/libs/WindowManager/Shell/res/values-mr/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"समजले"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"अलीकडील कोणतेही बबल नाहीत"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"अलीकडील बबल आणि डिसमिस केलेले बबल येथे दिसतील"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"बबल कधीही नियंत्रित करा"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"कोणती ॲप्स आणि संभाषणे बबल होऊ शकतात हे व्यवस्थापित करण्यासाठी येथे टॅप करा"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string> diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml index 054d2968e5a2..82d84e8da6d9 100644 --- a/libs/WindowManager/Shell/res/values-ms/strings.xml +++ b/libs/WindowManager/Shell/res/values-ms/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Tiada gelembung terbaharu"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Gelembung baharu dan gelembung yang diketepikan akan dipaparkan di sini"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kawal gelembung pada bila-bila masa"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Ketik di sini untuk mengurus apl dan perbualan yang boleh menggunakan gelembung"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Gelembung"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Urus"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Gelembung diketepikan."</string> diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml index 8af8bf48a0d8..2e88ab341984 100644 --- a/libs/WindowManager/Shell/res/values-my/strings.xml +++ b/libs/WindowManager/Shell/res/values-my/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"နားလည်ပြီ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"လတ်တလော ပူဖောင်းကွက်များ မရှိပါ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"လတ်တလော ပူဖောင်းကွက်များနှင့် ပိတ်လိုက်သော ပူဖောင်းကွက်များကို ဤနေရာတွင် မြင်ရပါမည်"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ပူဖောင်းကွက်ကို အချိန်မရွေး ထိန်းချုပ်ရန်"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ပူဖောင်းကွက်သုံးနိုင်သည့် အက်ပ်နှင့် စကားဝိုင်းများ စီမံရန် ဤနေရာကို တို့ပါ"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string> diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml index 8ac35371ee8a..f7ea9ce78dd8 100644 --- a/libs/WindowManager/Shell/res/values-nb/strings.xml +++ b/libs/WindowManager/Shell/res/values-nb/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Greit"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ingen nylige bobler"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Nylige bobler og avviste bobler vises her"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontroller bobler når som helst"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Trykk her for å administrere hvilke apper og samtaler som kan vises i bobler"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Boble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Administrer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Boblen er avvist."</string> diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml index a46e356acce1..3f6dc046c10b 100644 --- a/libs/WindowManager/Shell/res/values-ne/strings.xml +++ b/libs/WindowManager/Shell/res/values-ne/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"बुझेँ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"हालैका बबलहरू छैनन्"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"हालैका बबल र खारेज गरिएका बबलहरू यहाँ देखिने छन्"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"जुनसुकै बेला बबलसम्बन्धी सुविधा नियन्त्रण गर्नुहोस्"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"कुन एप र कुराकानी बबल प्रयोग गर्न सक्छन् भन्ने कुराको व्यवस्थापन गर्न यहाँ ट्याप गर्नुहोस्"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string> diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml index ed013153c80a..978ed3ccad3c 100644 --- a/libs/WindowManager/Shell/res/values-nl/strings.xml +++ b/libs/WindowManager/Shell/res/values-nl/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Geen recente bubbels"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Recente bubbels en gesloten bubbels zie je hier"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bubbels beheren wanneer je wilt"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tik hier om te beheren welke apps en gesprekken als bubbel kunnen worden getoond"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbel"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Beheren"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubbel gesloten."</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index 8465907f3836..b66448b6308f 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ବୁଝିଗଲି"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ବର୍ତ୍ତମାନ କୌଣସି ବବଲ୍ ନାହିଁ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ବର୍ତ୍ତମାନର ଏବଂ ଖାରଜ କରାଯାଇଥିବା ବବଲଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯିବ"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ଯେ କୌଣସି ସମୟରେ ବବଲଗୁଡ଼ିକ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"କେଉଁ ଆପ୍ସ ଓ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ବବଲ ହୋଇପାରିବ ତାହା ପରିଚାଳନା କରିବାକୁ ଏଠାରେ ଟାପ କରନ୍ତୁ"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string> diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml index 243fec3b4417..72cb92053e56 100644 --- a/libs/WindowManager/Shell/res/values-pa/strings.xml +++ b/libs/WindowManager/Shell/res/values-pa/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ਸਮਝ ਲਿਆ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ਕੋਈ ਹਾਲੀਆ ਬਬਲ ਨਹੀਂ"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ਹਾਲੀਆ ਬਬਲ ਅਤੇ ਖਾਰਜ ਕੀਤੇ ਬਬਲ ਇੱਥੇ ਦਿਸਣਗੇ"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ਬਬਲ ਦੀ ਸੁਵਿਧਾ ਨੂੰ ਕਿਸੇ ਵੀ ਵੇਲੇ ਕੰਟਰੋਲ ਕਰੋ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ਇਹ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਇੱਥੇ ਟੈਪ ਕਰੋ ਕਿ ਕਿਹੜੀਆਂ ਐਪਾਂ ਅਤੇ ਗੱਲਾਂਬਾਤਾਂ ਬਬਲ ਹੋ ਸਕਦੀਆਂ ਹਨ"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string> diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml index 34bc1a08207f..24c1f1410fde 100644 --- a/libs/WindowManager/Shell/res/values-pl/strings.xml +++ b/libs/WindowManager/Shell/res/values-pl/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Brak ostatnich dymków"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tutaj będą pojawiać się ostatnie i odrzucone dymki"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Zarządzaj dymkami, kiedy chcesz"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Kliknij tutaj, aby zarządzać wyświetlaniem aplikacji i rozmów jako dymków"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Dymek"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Zarządzaj"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Zamknięto dymek"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml index 85f2fa48b81f..69002026f2e5 100644 --- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ok"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e dispensados aparecerão aqui"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões a qualquer momento"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerenciar quais apps e conversas podem aparecer em balões"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index 083e2e7143dc..853c682b5089 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e ignorados vão aparecer aqui."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões em qualquer altura"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerir que apps e conversas podem aparecer em balões"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string> diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml index 85f2fa48b81f..69002026f2e5 100644 --- a/libs/WindowManager/Shell/res/values-pt/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ok"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nenhum balão recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Os balões recentes e dispensados aparecerão aqui"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controle os balões a qualquer momento"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Toque aqui para gerenciar quais apps e conversas podem aparecer em balões"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bolha"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerenciar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão dispensado."</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 6e8d1160d08c..7356f7cf08d2 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nu există baloane recente"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Baloanele recente și baloanele respinse vor apărea aici"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Controlează baloanele oricând"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Atinge aici pentru a gestiona aplicațiile și conversațiile care pot apărea în balon"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionează"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string> diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml index c3cd9594552a..61e3ec9b7da2 100644 --- a/libs/WindowManager/Shell/res/values-ru/strings.xml +++ b/libs/WindowManager/Shell/res/values-ru/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"ОК"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нет недавних всплывающих чатов"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Здесь будут появляться недавние и скрытые всплывающие чаты."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Всплывающие чаты"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Укажите приложения и разговоры, для которых разрешены всплывающие чаты."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string> diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml index a1e246a95bf2..ac78385b9644 100644 --- a/libs/WindowManager/Shell/res/values-si/strings.xml +++ b/libs/WindowManager/Shell/res/values-si/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"තේරුණා"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"මෑත බුබුලු නැත"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"මෑත බුබුලු සහ ඉවත ලූ බුබුලු මෙහි දිස් වනු ඇත"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ඕනෑම වේලාවක බුබුලු පාලනය කරන්න"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"බුබුලු කළ හැකි යෙදුම් සහ සංවාද කළමනාකරණය කිරීමට මෙහි තට්ටු කරන්න"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string> diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml index c27425d6948a..d659d51afc5f 100644 --- a/libs/WindowManager/Shell/res/values-sk/strings.xml +++ b/libs/WindowManager/Shell/res/values-sk/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Dobre"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Žiadne nedávne bubliny"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tu sa budú zobrazovať nedávne a zavreté bubliny"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Ovládajte bubliny kedykoľvek"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Klepnite tu a spravujte, ktoré aplikácie a konverzácie môžu ovládať bubliny"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovať"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina bola zavretá."</string> diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml index e3dcca899bf2..91871fbf94ec 100644 --- a/libs/WindowManager/Shell/res/values-sl/strings.xml +++ b/libs/WindowManager/Shell/res/values-sl/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"V redu"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Ni nedavnih oblačkov"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Tukaj bodo prikazani tako nedavni kot tudi opuščeni oblački"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Upravljanje oblačkov"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Dotaknite se tukaj za upravljanje aplikacij in pogovorov, ki so lahko prikazani v oblačkih"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Mehurček"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblaček je bil opuščen."</string> diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml index b5b2d1891cab..45eb04a45271 100644 --- a/libs/WindowManager/Shell/res/values-sq/strings.xml +++ b/libs/WindowManager/Shell/res/values-sq/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"E kuptova"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Nuk ka flluska të fundit"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Flluskat e fundit dhe flluskat e hequra do të shfaqen këtu"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrollo flluskat në çdo moment"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Trokit këtu për të menaxhuar aplikacionet e bisedat që do të shfaqen në flluska"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Flluskë"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Menaxho"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Flluska u hoq."</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 3404bca2bb9d..368df542796f 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Важи"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Нема недавних облачића"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Овде се приказују недавни и одбачени облачићи"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контролишите облачиће у сваком тренутку"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Додирните овде и одредите које апликације и конверзације могу да имају облачић"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string> diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml index 1f81e0fa5f64..35d5b7af2b62 100644 --- a/libs/WindowManager/Shell/res/values-sv/strings.xml +++ b/libs/WindowManager/Shell/res/values-sv/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Inga nya bubblor"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"De senaste bubblorna och ignorerade bubblor visas här"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Styr bubblor när som helst"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Tryck här för att hantera vilka appar och konversationer som får visas i bubblor"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubbla"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Hantera"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bubblan ignorerades."</string> diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml index 8ec4e3415a51..52e0a6960948 100644 --- a/libs/WindowManager/Shell/res/values-sw/strings.xml +++ b/libs/WindowManager/Shell/res/values-sw/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Nimeelewa"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hakuna viputo vya hivi majuzi"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Viputo vya hivi karibuni na vile vilivyoondolewa vitaonekana hapa"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Dhibiti viputo wakati wowote"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Gusa hapa ili udhibiti programu na mazungumzo yanayoweza kutumia viputo"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Kiputo"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Dhibiti"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Umeondoa kiputo."</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index 6a8559dc262c..98a7d679014c 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"சரி"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"சமீபத்திய குமிழ்கள் இல்லை"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"சமீபத்திய குமிழ்களும் நிராகரிக்கப்பட்ட குமிழ்களும் இங்கே தோன்றும்"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"எப்போது வேண்டுமானாலும் குமிழ்களைக் கட்டுப்படுத்துங்கள்"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"எந்தெந்த ஆப்ஸும் உரையாடல்களும் குமிழியாகலாம் என்பதை நிர்வகிக்க இங்கே தட்டுங்கள்"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string> diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml index 1c1e3cbd5697..70f810e21fcc 100644 --- a/libs/WindowManager/Shell/res/values-te/strings.xml +++ b/libs/WindowManager/Shell/res/values-te/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"అర్థమైంది"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ఇటీవలి బబుల్స్ ఏవీ లేవు"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"ఇటీవలి బబుల్స్ మరియు తీసివేసిన బబుల్స్ ఇక్కడ కనిపిస్తాయి"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"బబుల్స్ను ఎప్పుడైనా కంట్రోల్ చేయండి"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"ఏ యాప్లు, సంభాషణలను బబుల్ చేయాలో మేనేజ్ చేయడానికి ఇక్కడ ట్యాప్ చేయండి"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string> diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml index a0f0e275ba17..0efaab2d2f15 100644 --- a/libs/WindowManager/Shell/res/values-th/strings.xml +++ b/libs/WindowManager/Shell/res/values-th/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"รับทราบ"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"ไม่มีบับเบิลเมื่อเร็วๆ นี้"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"บับเบิลที่แสดงและที่ปิดไปเมื่อเร็วๆ นี้จะปรากฏที่นี่"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"ควบคุมบับเบิลได้ทุกเมื่อ"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"แตะที่นี่เพื่อจัดการแอปและการสนทนาที่แสดงเป็นบับเบิลได้"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string> diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml index 9bc17f091a30..e5d535015c52 100644 --- a/libs/WindowManager/Shell/res/values-tl/strings.xml +++ b/libs/WindowManager/Shell/res/values-tl/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Walang kamakailang bubble"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Lalabas dito ang mga kamakailang bubble at na-dismiss na bubble"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kontrolin ang mga bubble anumang oras"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Mag-tap dito para pamahalaan ang mga app at conversion na puwedeng mag-bubble"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bubble"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Pamahalaan"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Na-dismiss na ang bubble."</string> diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml index 059ec7340d69..8e7f1620354b 100644 --- a/libs/WindowManager/Shell/res/values-tr/strings.xml +++ b/libs/WindowManager/Shell/res/values-tr/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Anladım"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Son kapatılan baloncuk yok"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Son baloncuklar ve kapattığınız baloncuklar burada görünür"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Baloncukları istediğiniz zaman kontrol edin"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Buraya dokunarak baloncuk olarak gösterilecek uygulama ve görüşmeleri yönetin"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Baloncuk"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Yönet"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balon kapatıldı."</string> diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml index a4a4a78a8755..5c7c6c4dae30 100644 --- a/libs/WindowManager/Shell/res/values-uk/strings.xml +++ b/libs/WindowManager/Shell/res/values-uk/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Зрозуміло"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Немає нещодавніх спливаючих чатів"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Тут з\'являтимуться нещодавні й закриті спливаючі чати"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Контроль спливаючих чатів"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Натисніть тут, щоб вибрати, для яких додатків і розмов дозволити спливаючі чати"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string> diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml index b25f13eed644..451d048ca825 100644 --- a/libs/WindowManager/Shell/res/values-ur/strings.xml +++ b/libs/WindowManager/Shell/res/values-ur/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"سمجھ آ گئی"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"کوئی حالیہ بلبلہ نہیں"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حالیہ بلبلے اور برخاست شدہ بلبلے یہاں ظاہر ہوں گے"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کسی بھی وقت بلبلے کو کنٹرول کریں"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"یہ نظم کرنے کے لیے یہاں تھپتھپائیں کہ کون سی ایپس اور گفتگوئیں بلبلہ سکتی ہیں"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string> diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml index 5acf7293a060..4211ea7a5e7d 100644 --- a/libs/WindowManager/Shell/res/values-uz/strings.xml +++ b/libs/WindowManager/Shell/res/values-uz/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Hech qanday bulutcha topilmadi"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Eng oxirgi va yopilgan bulutchali chatlar shu yerda chiqadi"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Bulutchalardagi bildirishnomalar"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Bulutchalarda bildirishnomalar chiqishiga ruxsat beruvchi ilova va suhbatlarni tanlang."</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Pufaklar"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Boshqarish"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulutcha yopildi."</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 0777abc087fa..0a0205d8f591 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Đã hiểu"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Không có bong bóng trò chuyện nào gần đây"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Bong bóng trò chuyện đã đóng và bong bóng trò chuyện gần đây sẽ xuất hiện ở đây"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Kiểm soát bong bóng bất cứ lúc nào"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Nhấn vào đây để quản lý việc dùng bong bóng cho các ứng dụng và cuộc trò chuyện"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml index cde5fe3045da..29dc077469e6 100644 --- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"知道了"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近没有对话泡"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"此处会显示最近的对话泡和已关闭的对话泡"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"随时控制对话泡"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"点按此处即可管理哪些应用和对话可以显示对话泡"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭对话泡。"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index fcb0c91f41d5..0755d61e6a6d 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"知道了"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"沒有最近曾使用的小視窗"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近使用和關閉的小視窗會在這裡顯示"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"隨時控制對話氣泡"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"輕按這裡即可管理哪些應用程式和對話可以使用對話氣泡"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string> diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml index f272e91fe7a8..f93188343fdf 100644 --- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"我知道了"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"最近沒有任何對話框"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"最近的對話框和已關閉的對話框會顯示在這裡"</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"你隨時可以控管對話框的各項設定"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"輕觸這裡即可管理哪些應用程式和對話可顯示對話框"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string> diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml index c1ba6ee01cef..3ba0abee2a95 100644 --- a/libs/WindowManager/Shell/res/values-zu/strings.xml +++ b/libs/WindowManager/Shell/res/values-zu/strings.xml @@ -76,10 +76,8 @@ <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"Ngiyezwa"</string> <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Awekho amabhamuza akamuva"</string> <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Amabhamuza akamuva namabhamuza asusiwe azobonakala lapha."</string> - <!-- no translation found for bubble_bar_education_manage_title (6148404487810835924) --> - <skip /> - <!-- no translation found for bubble_bar_education_manage_text (3199732148641842038) --> - <skip /> + <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"Lawula amabhamuza noma nini"</string> + <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"Thepha lapha ukuze ulawule ukuthi yimaphi ama-app kanye nezingxoxo ezingenza amabhamuza"</string> <string name="notification_bubble_title" msgid="6082910224488253378">"Ibhamuza"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Phatha"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ibhamuza licashisiwe."</string> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 7edf2fc84f48..cba86c8b3dcf 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -428,9 +428,12 @@ <!-- The height of the handle menu's "Windowing" pill in desktop mode. --> <dimen name="desktop_mode_handle_menu_windowing_pill_height">52dp</dimen> - <!-- The height of the handle menu's "More Actions" pill in desktop mode. --> + <!-- The height of the handle menu's "More Actions" pill in desktop mode, but not freeform. --> <dimen name="desktop_mode_handle_menu_more_actions_pill_height">156dp</dimen> + <!-- The height of the handle menu's "More Actions" pill in freeform desktop windowing mode. --> + <dimen name="desktop_mode_handle_menu_more_actions_pill_freeform_height">104dp</dimen> + <!-- The top margin of the handle menu in desktop mode. --> <dimen name="desktop_mode_handle_menu_margin_top">4dp</dimen> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java index 72702e7c2b88..b828aac39040 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayChangeController.java @@ -18,6 +18,7 @@ package com.android.wm.shell.common; import android.annotation.Nullable; import android.os.RemoteException; +import android.os.Trace; import android.util.Slog; import android.view.IDisplayChangeWindowCallback; import android.view.IDisplayChangeWindowController; @@ -40,6 +41,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class DisplayChangeController { private static final String TAG = DisplayChangeController.class.getSimpleName(); + private static final String HANDLE_DISPLAY_CHANGE_TRACE_TAG = "HandleRemoteDisplayChange"; private final ShellExecutor mMainExecutor; private final IWindowManager mWmService; @@ -81,9 +83,15 @@ public class DisplayChangeController { /** Query all listeners for changes that should happen on display change. */ void dispatchOnDisplayChange(WindowContainerTransaction outWct, int displayId, int fromRotation, int toRotation, DisplayAreaInfo newDisplayAreaInfo) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.beginSection("dispatchOnDisplayChange"); + } for (OnDisplayChangingListener c : mDisplayChangeListener) { c.onDisplayChange(displayId, fromRotation, toRotation, newDisplayAreaInfo, outWct); } + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.endSection(); + } } private void onDisplayChange(int displayId, int fromRotation, int toRotation, @@ -94,6 +102,10 @@ public class DisplayChangeController { callback.continueDisplayChange(t); } catch (RemoteException e) { Slog.e(TAG, "Failed to continue handling display change", e); + } finally { + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.endAsyncSection(HANDLE_DISPLAY_CHANGE_TRACE_TAG, callback.hashCode()); + } } } @@ -103,6 +115,9 @@ public class DisplayChangeController { @Override public void onDisplayChange(int displayId, int fromRotation, int toRotation, DisplayAreaInfo newDisplayAreaInfo, IDisplayChangeWindowCallback callback) { + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.beginAsyncSection(HANDLE_DISPLAY_CHANGE_TRACE_TAG, callback.hashCode()); + } mMainExecutor.execute(() -> DisplayChangeController.this .onDisplayChange(displayId, fromRotation, toRotation, newDisplayAreaInfo, callback)); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java index e3922d65215c..018d674e5427 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java @@ -1059,7 +1059,21 @@ public class PipTransition extends PipTransitionController { private void resetPrevPip(@NonNull TransitionInfo.Change prevPipTaskChange, @NonNull SurfaceControl.Transaction startTransaction) { final SurfaceControl leash = prevPipTaskChange.getLeash(); - startTransaction.remove(leash); + final Rect bounds = prevPipTaskChange.getEndAbsBounds(); + final Point offset = prevPipTaskChange.getEndRelOffset(); + bounds.offset(-offset.x, -offset.y); + + startTransaction.setWindowCrop(leash, null); + startTransaction.setMatrix(leash, 1, 0, 0, 1); + startTransaction.setCornerRadius(leash, 0); + startTransaction.setPosition(leash, bounds.left, bounds.top); + + if (mHasFadeOut && prevPipTaskChange.getTaskInfo().isVisible()) { + if (mPipAnimationController.getCurrentAnimator() != null) { + mPipAnimationController.getCurrentAnimator().cancel(); + } + startTransaction.setAlpha(leash, 1); + } mHasFadeOut = false; mCurrentPipTaskToken = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index ce8191067ae9..c18973132364 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -64,7 +64,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL Handler handler, Choreographer choreographer, SyncTransactionQueue syncQueue) { - super(context, displayController, taskOrganizer, taskInfo, taskSurface); + super(context, displayController, taskOrganizer, taskInfo, taskSurface, + taskInfo.getConfiguration()); mHandler = handler; mChoreographer = choreographer; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 3e21c8cbfd4c..e954f3b4a1d5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -104,11 +104,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface, + Configuration windowDecorConfig, Handler handler, Choreographer choreographer, SyncTransactionQueue syncQueue, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { - super(context, displayController, taskOrganizer, taskInfo, taskSurface); + super(context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig); mHandler = handler; mChoreographer = choreographer; @@ -118,17 +119,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin loadAppInfo(); } - @Override - protected Configuration getConfigurationWithOverrides( - ActivityManager.RunningTaskInfo taskInfo) { - Configuration configuration = taskInfo.getConfiguration(); - if (DesktopTasksController.isDesktopDensityOverrideSet()) { - // Density is overridden for desktop tasks. Keep system density for window decoration. - configuration.densityDpi = mContext.getResources().getConfiguration().densityDpi; - } - return configuration; - } - void setCaptionListeners( View.OnClickListener onCaptionButtonClickListener, View.OnTouchListener onCaptionTouchListener, @@ -194,6 +184,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin mRelayoutParams.mShadowRadiusId = shadowRadiusID; mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw; + mRelayoutParams.mWindowDecorConfig = DesktopTasksController.isDesktopDensityOverrideSet() + ? mContext.getResources().getConfiguration() // Use system context + : mTaskInfo.configuration; // Use task configuration + mRelayoutParams.mCornerRadius = (int) ScreenDecorationsUtils.getWindowCornerRadius(mContext); relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult); @@ -614,12 +608,17 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin Choreographer choreographer, SyncTransactionQueue syncQueue, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { + final Configuration windowDecorConfig = + DesktopTasksController.isDesktopDensityOverrideSet() + ? context.getResources().getConfiguration() // Use system context + : taskInfo.configuration; // Use task configuration return new DesktopModeWindowDecoration( context, displayController, taskOrganizer, taskInfo, taskSurface, + windowDecorConfig, handler, choreographer, syncQueue, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java index ca7cbfd9006c..42b1240b0d49 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java @@ -186,7 +186,12 @@ class HandleMenu { // More Actions pill setup. final View moreActionsPillView = mMoreActionsPill.mWindowViewHost.getView(); final Button closeBtn = moreActionsPillView.findViewById(R.id.close_button); - closeBtn.setOnClickListener(mOnClickListener); + if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) { + closeBtn.setVisibility(View.GONE); + } else { + closeBtn.setVisibility(View.VISIBLE); + closeBtn.setOnClickListener(mOnClickListener); + } final Button selectBtn = moreActionsPillView.findViewById(R.id.select_button); selectBtn.setOnClickListener(mOnClickListener); } @@ -228,7 +233,6 @@ class HandleMenu { /** * Update pill layout, in case task changes have caused positioning to change. - * @param t */ void relayout(SurfaceControl.Transaction t) { if (mAppInfoPill != null) { @@ -245,10 +249,12 @@ class HandleMenu { mMoreActionsPillPosition.x, mMoreActionsPillPosition.y); } } + /** * Check a passed MotionEvent if a click has occurred on any button on this caption * Note this should only be called when a regular onClick is not possible * (i.e. the button was clicked through status bar layer) + * * @param ev the MotionEvent to compare against. */ void checkClickEvent(MotionEvent ev) { @@ -267,6 +273,7 @@ class HandleMenu { * A valid menu input is one of the following: * An input that happens in the menu views. * Any input before the views have been laid out. + * * @param inputPoint the input to compare against. */ boolean isValidMenuInput(PointF inputPoint) { @@ -297,7 +304,6 @@ class HandleMenu { /** * Check if the views for handle menu can be seen. - * @return */ private boolean viewsLaidOut() { return mAppInfoPill.mWindowViewHost.getView().isLaidOut(); @@ -318,8 +324,7 @@ class HandleMenu { R.dimen.desktop_mode_handle_menu_app_info_pill_height); mWindowingPillHeight = loadDimensionPixelSize(resources, R.dimen.desktop_mode_handle_menu_windowing_pill_height); - mMoreActionsPillHeight = loadDimensionPixelSize(resources, - R.dimen.desktop_mode_handle_menu_more_actions_pill_height); + mMoreActionsPillHeight = shouldShowCloseButton(resources); mShadowRadius = loadDimensionPixelSize(resources, R.dimen.desktop_mode_handle_menu_shadow_radius); mCornerRadius = loadDimensionPixelSize(resources, @@ -333,6 +338,14 @@ class HandleMenu { return resources.getDimensionPixelSize(resourceId); } + private int shouldShowCloseButton(Resources resources) { + return (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) + ? loadDimensionPixelSize(resources, + R.dimen.desktop_mode_handle_menu_more_actions_pill_freeform_height) + : loadDimensionPixelSize(resources, + R.dimen.desktop_mode_handle_menu_more_actions_pill_height); + } + void close() { mAppInfoPill.releaseView(); mAppInfoPill = null; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 0b0d9d5086f4..8d76fc6c542b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -115,6 +115,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> SurfaceControl mCaptionContainerSurface; private WindowlessWindowManager mCaptionWindowManager; private SurfaceControlViewHost mViewHost; + private Configuration mWindowDecorConfig; private final Binder mOwner = new Binder(); private final Rect mCaptionInsetsRect = new Rect(); @@ -125,8 +126,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> DisplayController displayController, ShellTaskOrganizer taskOrganizer, RunningTaskInfo taskInfo, - SurfaceControl taskSurface) { - this(context, displayController, taskOrganizer, taskInfo, taskSurface, + SurfaceControl taskSurface, + Configuration windowDecorConfig) { + this(context, displayController, taskOrganizer, taskInfo, taskSurface, windowDecorConfig, SurfaceControl.Builder::new, SurfaceControl.Transaction::new, WindowContainerTransaction::new, new SurfaceControlViewHostFactory() {}); } @@ -137,6 +139,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> ShellTaskOrganizer taskOrganizer, RunningTaskInfo taskInfo, SurfaceControl taskSurface, + Configuration windowDecorConfig, Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, Supplier<WindowContainerTransaction> windowContainerTransactionSupplier, @@ -152,17 +155,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mSurfaceControlViewHostFactory = surfaceControlViewHostFactory; mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId); - mDecorWindowContext = mContext.createConfigurationContext( - getConfigurationWithOverrides(mTaskInfo)); - } - - /** - * Get {@link Configuration} from supplied {@link RunningTaskInfo}. - * - * Allows values to be overridden before returning the configuration. - */ - protected Configuration getConfigurationWithOverrides(RunningTaskInfo taskInfo) { - return taskInfo.getConfiguration(); + mWindowDecorConfig = windowDecorConfig; + mDecorWindowContext = mContext.createConfigurationContext(mWindowDecorConfig); } /** @@ -179,7 +173,6 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> RelayoutResult<T> outResult) { outResult.reset(); - final Configuration oldTaskConfig = mTaskInfo.getConfiguration(); if (params.mRunningTaskInfo != null) { mTaskInfo = params.mRunningTaskInfo; } @@ -198,8 +191,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> outResult.mRootView = rootView; rootView = null; // Clear it just in case we use it accidentally - final Configuration taskConfig = getConfigurationWithOverrides(mTaskInfo); - if (oldTaskConfig.densityDpi != taskConfig.densityDpi + + final int oldDensityDpi = mWindowDecorConfig.densityDpi; + mWindowDecorConfig = params.mWindowDecorConfig != null ? params.mWindowDecorConfig + : mTaskInfo.getConfiguration(); + if (oldDensityDpi != mWindowDecorConfig.densityDpi || mDisplay == null || mDisplay.getDisplayId() != mTaskInfo.displayId || oldLayoutResId != mLayoutResId) { @@ -209,7 +205,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> outResult.mRootView = null; return; } - mDecorWindowContext = mContext.createConfigurationContext(taskConfig); + mDecorWindowContext = mContext.createConfigurationContext(mWindowDecorConfig); if (params.mLayoutResId != 0) { outResult.mRootView = (T) LayoutInflater.from(mDecorWindowContext) .inflate(params.mLayoutResId, null); @@ -222,6 +218,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> } final Resources resources = mDecorWindowContext.getResources(); + final Configuration taskConfig = mTaskInfo.getConfiguration(); final Rect taskBounds = taskConfig.windowConfiguration.getBounds(); outResult.mWidth = taskBounds.width(); outResult.mHeight = taskBounds.height(); @@ -470,6 +467,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionX; int mCaptionY; + Configuration mWindowDecorConfig; + boolean mApplyStartTransactionOnDraw; void reset() { @@ -484,6 +483,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionY = 0; mApplyStartTransactionOnDraw = false; + mWindowDecorConfig = null; } } diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index 434b008a8e83..eb650caf04e2 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -126,6 +126,7 @@ java_defaults { "flickertestapplib", "flickerlib", "flickerlib-helpers", + "flickerlib-trace_processor_shell", "platform-test-annotations", "wm-flicker-common-app-helpers", "wm-flicker-common-assertions", diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml index 87b20ed6305e..5e6a6c9f56dc 100644 --- a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml +++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml @@ -73,7 +73,9 @@ <option name="shell-timeout" value="6600s"/> <option name="test-timeout" value="6000s"/> <option name="hidden-api-checks" value="false"/> + <!-- TODO(b/288396763): re-enable when PerfettoListener is fixed <option name="device-listeners" value="android.device.collectors.PerfettoListener"/> + --> <!-- PerfettoListener related arguments --> <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/> <option name="instrumentation-arg" diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml index 6a87de47def4..ae130b8f6f7d 100644 --- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml @@ -45,9 +45,13 @@ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <!-- Enable bubble notification--> <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> - <!-- Allow the test to write directly to /sdcard/ --> - <application android:requestLegacyExternalStorage="true" android:largeHeap="true"> + <!-- Allow the test to write directly to /sdcard/ and connect to trace processor --> + <application android:requestLegacyExternalStorage="true" + android:networkSecurityConfig="@xml/network_security_config" + android:largeHeap="true"> <uses-library android:name="android.test.runner"/> <service android:name=".NotificationListener" diff --git a/libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml b/libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml new file mode 100644 index 000000000000..4bd9ca049f55 --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/res/xml/network_security_config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config> diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java index 7fc1c99bb44e..76bc25aa66ef 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java @@ -39,6 +39,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Point; @@ -116,6 +117,7 @@ public class WindowDecorationTests extends ShellTestCase { private SurfaceControl.Transaction mMockSurfaceControlFinishT; private SurfaceControl.Transaction mMockSurfaceControlAddWindowT; private WindowDecoration.RelayoutParams mRelayoutParams = new WindowDecoration.RelayoutParams(); + private Configuration mWindowConfiguration = new Configuration(); private int mCaptionMenuWidthId; private int mCaptionMenuShadowRadiusId; private int mCaptionMenuCornerRadiusId; @@ -296,6 +298,7 @@ public class WindowDecorationTests extends ShellTestCase { taskInfo.isFocused = true; // Density is 2. Shadow radius is 10px. Caption height is 64px. taskInfo.configuration.densityDpi = DisplayMetrics.DENSITY_DEFAULT * 2; + mWindowConfiguration.densityDpi = taskInfo.configuration.densityDpi; final SurfaceControl taskSurface = mock(SurfaceControl.class); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo, taskSurface); @@ -516,7 +519,7 @@ public class WindowDecorationTests extends ShellTestCase { private TestWindowDecoration createWindowDecoration( ActivityManager.RunningTaskInfo taskInfo, SurfaceControl testSurface) { return new TestWindowDecoration(mContext, mMockDisplayController, mMockShellTaskOrganizer, - taskInfo, testSurface, + taskInfo, testSurface, mWindowConfiguration, new MockObjectSupplier<>(mMockSurfaceControlBuilders, () -> createMockSurfaceControlBuilder(mock(SurfaceControl.class))), new MockObjectSupplier<>(mMockSurfaceControlTransactions, @@ -556,13 +559,15 @@ public class WindowDecorationTests extends ShellTestCase { TestWindowDecoration(Context context, DisplayController displayController, ShellTaskOrganizer taskOrganizer, ActivityManager.RunningTaskInfo taskInfo, SurfaceControl taskSurface, + Configuration windowConfiguration, Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, Supplier<WindowContainerTransaction> windowContainerTransactionSupplier, SurfaceControlViewHostFactory surfaceControlViewHostFactory) { super(context, displayController, taskOrganizer, taskInfo, taskSurface, - surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, - windowContainerTransactionSupplier, surfaceControlViewHostFactory); + windowConfiguration, surfaceControlBuilderSupplier, + surfaceControlTransactionSupplier, windowContainerTransactionSupplier, + surfaceControlViewHostFactory); } @Override diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index e2b541aa5ecb..ee3b2e48fe4b 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -25,6 +25,7 @@ #include <android/sync.h> #include <gui/TraceUtils.h> #include <include/gpu/ganesh/SkSurfaceGanesh.h> +#include <include/gpu/ganesh/vk/GrVkBackendSurface.h> #include <ui/FatVector.h> #include <vk/GrVkExtensions.h> #include <vk/GrVkTypes.h> @@ -599,7 +600,7 @@ nsecs_t VulkanManager::finishFrame(SkSurface* surface) { surface, SkSurfaces::BackendHandleAccess::kFlushRead); if (backendRenderTarget.isValid()) { GrVkImageInfo info; - if (backendRenderTarget.getVkImageInfo(&info)) { + if (GrBackendRenderTargets::GetVkImageInfo(backendRenderTarget, &info)) { image = info.fImage; } else { ALOGE("Frame boundary: backend is not vulkan"); diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java index 0eb657aba033..fd3e5a22e969 100644 --- a/location/java/android/location/Location.java +++ b/location/java/android/location/Location.java @@ -709,11 +709,9 @@ public class Location implements Parcelable { /** * Returns the Mean Sea Level altitude of this location in meters. * - * @throws IllegalStateException if {@link #hasMslAltitude()} is false. + * <p>This is only valid if {@link #hasMslAltitude()} is true. */ public @FloatRange double getMslAltitudeMeters() { - Preconditions.checkState(hasMslAltitude(), - "The Mean Sea Level altitude of this location is not set."); return mMslAltitudeMeters; } @@ -744,11 +742,9 @@ public class Location implements Parcelable { * percentile confidence level. This means that there is 68% chance that the true Mean Sea Level * altitude of this location falls within {@link #getMslAltitudeMeters()} +/- this uncertainty. * - * @throws IllegalStateException if {@link #hasMslAltitudeAccuracy()} is false. + * <p>This is only valid if {@link #hasMslAltitudeAccuracy()} is true. */ public @FloatRange(from = 0.0) float getMslAltitudeAccuracyMeters() { - Preconditions.checkState(hasMslAltitudeAccuracy(), - "The Mean Sea Level altitude accuracy of this location is not set."); return mMslAltitudeAccuracyMeters; } diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 3f013de8dad6..61b5fd5fb0ec 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -29,6 +29,7 @@ import android.content.pm.PackageManager; import android.media.audio.common.AidlConversion; import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; +import android.media.audiopolicy.AudioMixingRule; import android.media.audiopolicy.AudioProductStrategy; import android.os.Build; import android.os.IBinder; @@ -1955,6 +1956,11 @@ public class AudioSystem /** @hide */ public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register); + /** @hide */ + public static native int updatePolicyMixes( + AudioMix[] mixes, + AudioMixingRule[] updatedMixingRules); + /** @hide see AudioPolicy.setUidDeviceAffinities() */ public static native int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses); diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index e45ef404995c..0e7718b060bc 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -54,6 +54,8 @@ import android.media.IVolumeController; import android.media.PlayerBase; import android.media.VolumeInfo; import android.media.VolumePolicy; +import android.media.audiopolicy.AudioMix; +import android.media.audiopolicy.AudioMixingRule; import android.media.audiopolicy.AudioPolicyConfig; import android.media.audiopolicy.AudioProductStrategy; import android.media.audiopolicy.AudioVolumeGroup; @@ -356,6 +358,11 @@ interface IAudioService { int removeMixForPolicy(in AudioPolicyConfig policyConfig, in IAudioPolicyCallback pcb); + @EnforcePermission("MODIFY_AUDIO_ROUTING") + int updateMixingRulesForPolicy(in AudioMix[] mixesToUpdate, + in AudioMixingRule[] updatedMixingRules, + in IAudioPolicyCallback pcb); + int setFocusPropertiesForPolicy(int duckingBehavior, in IAudioPolicyCallback pcb); void setVolumePolicy(in VolumePolicy policy); diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java index ea261852bb9f..1de08810307e 100644 --- a/media/java/android/media/MediaMetadataRetriever.java +++ b/media/java/android/media/MediaMetadataRetriever.java @@ -1155,7 +1155,7 @@ public class MediaMetadataRetriever implements AutoCloseable { public static final int OPTION_CLOSEST = 0x03; /** @hide */ - @IntDef(flag = true, prefix = { "OPTION_" }, value = { + @IntDef(flag = false, prefix = { "OPTION_" }, value = { OPTION_PREVIOUS_SYNC, OPTION_NEXT_SYNC, OPTION_CLOSEST_SYNC, diff --git a/media/java/android/media/audiopolicy/AudioMix.aidl b/media/java/android/media/audiopolicy/AudioMix.aidl new file mode 100644 index 000000000000..d17a644c93a1 --- /dev/null +++ b/media/java/android/media/audiopolicy/AudioMix.aidl @@ -0,0 +1,3 @@ +package android.media.audiopolicy; + +parcelable AudioMix;
\ No newline at end of file diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index d0270d3d3246..48b476651c91 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -21,12 +21,15 @@ import static android.media.AudioSystem.isRemoteSubmixDevice; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioSystem; import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; @@ -38,12 +41,12 @@ import java.util.Objects; * @hide */ @SystemApi -public class AudioMix { +public class AudioMix implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private AudioMixingRule mRule; + private @NonNull AudioMixingRule mRule; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - private AudioFormat mFormat; + private @NonNull AudioFormat mFormat; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int mRouteFlags; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -54,7 +57,7 @@ public class AudioMix { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) int mCallbackFlags; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - String mDeviceAddress; + @NonNull String mDeviceAddress; // initialized in constructor, read by AudioPolicyConfig @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -63,10 +66,11 @@ public class AudioMix { /** * All parameters are guaranteed valid through the Builder. */ - private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags, - int deviceType, String deviceAddress) { - mRule = rule; - mFormat = format; + private AudioMix(@NonNull AudioMixingRule rule, @NonNull AudioFormat format, + int routeFlags, int callbackFlags, + int deviceType, @Nullable String deviceAddress) { + mRule = Objects.requireNonNull(rule); + mFormat = Objects.requireNonNull(format); mRouteFlags = routeFlags; mMixType = rule.getTargetMixType(); mCallbackFlags = callbackFlags; @@ -187,6 +191,15 @@ public class AudioMix { } /** @hide */ + public void setAudioMixingRule(@NonNull AudioMixingRule rule) { + if (mRule.getTargetMixType() != rule.getTargetMixType()) { + throw new UnsupportedOperationException( + "Target mix role of updated rule doesn't match the mix role of the AudioMix"); + } + mRule = Objects.requireNonNull(rule); + } + + /** @hide */ public String getRegistration() { return mDeviceAddress; } @@ -269,6 +282,49 @@ public class AudioMix { return Objects.hash(mRouteFlags, mRule, mMixType, mFormat); } + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + // write mix route flags + dest.writeInt(mRouteFlags); + // write callback flags + dest.writeInt(mCallbackFlags); + // write device information + dest.writeInt(mDeviceSystemType); + dest.writeString8(mDeviceAddress); + mFormat.writeToParcel(dest, flags); + mRule.writeToParcel(dest, flags); + } + + public static final @NonNull Parcelable.Creator<AudioMix> CREATOR = new Parcelable.Creator<>() { + /** + * Rebuilds an AudioMix previously stored with writeToParcel(). + * + * @param p Parcel object to read the AudioMix from + * @return a new AudioMix created from the data in the parcel + */ + public AudioMix createFromParcel(Parcel p) { + final AudioMix.Builder mixBuilder = new AudioMix.Builder(); + // read mix route flags + mixBuilder.setRouteFlags(p.readInt()); + // read callback flags + mixBuilder.setCallbackFlags(p.readInt()); + // read device information + mixBuilder.setDevice(p.readInt(), p.readString8()); + mixBuilder.setFormat(AudioFormat.CREATOR.createFromParcel(p)); + mixBuilder.setMixingRule(AudioMixingRule.CREATOR.createFromParcel(p)); + return mixBuilder.build(); + } + + public AudioMix[] newArray(int size) { + return new AudioMix[size]; + } + }; + /** @hide */ @IntDef(flag = true, value = { ROUTE_FLAG_RENDER, ROUTE_FLAG_LOOP_BACK } ) @@ -298,7 +354,7 @@ public class AudioMix { * @param rule a non-null {@link AudioMixingRule} instance. * @throws IllegalArgumentException */ - public Builder(AudioMixingRule rule) + public Builder(@NonNull AudioMixingRule rule) throws IllegalArgumentException { if (rule == null) { throw new IllegalArgumentException("Illegal null AudioMixingRule argument"); @@ -313,7 +369,7 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - Builder setMixingRule(AudioMixingRule rule) + Builder setMixingRule(@NonNull AudioMixingRule rule) throws IllegalArgumentException { if (rule == null) { throw new IllegalArgumentException("Illegal null AudioMixingRule argument"); @@ -358,7 +414,7 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - public Builder setFormat(AudioFormat format) + public Builder setFormat(@NonNull AudioFormat format) throws IllegalArgumentException { if (format == null) { throw new IllegalArgumentException("Illegal null AudioFormat argument"); diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.aidl b/media/java/android/media/audiopolicy/AudioMixingRule.aidl new file mode 100644 index 000000000000..5c06538b74c2 --- /dev/null +++ b/media/java/android/media/audiopolicy/AudioMixingRule.aidl @@ -0,0 +1,3 @@ +package android.media.audiopolicy; + +parcelable AudioMixingRule;
\ No newline at end of file diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index 9c0b825fbfa3..e5debb8132ea 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -26,8 +26,11 @@ import android.media.AudioAttributes; import android.media.MediaRecorder; import android.os.Build; import android.os.Parcel; +import android.os.Parcelable; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import java.lang.annotation.Retention; import java.util.ArrayList; import java.util.Collection; @@ -50,7 +53,7 @@ import java.util.Set; * </pre> */ @SystemApi -public class AudioMixingRule { +public class AudioMixingRule implements Parcelable { private AudioMixingRule(int mixType, Collection<AudioMixMatchCriterion> criteria, boolean allowPrivilegedMediaPlaybackCapture, @@ -130,7 +133,7 @@ public class AudioMixingRule { RULE_EXCLUSION_MASK | RULE_MATCH_AUDIO_SESSION_ID; /** @hide */ - public static final class AudioMixMatchCriterion { + public static final class AudioMixMatchCriterion implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) final AudioAttributes mAttr; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -139,18 +142,44 @@ public class AudioMixingRule { final int mRule; /** input parameters must be valid */ - AudioMixMatchCriterion(AudioAttributes attributes, int rule) { + @VisibleForTesting + public AudioMixMatchCriterion(AudioAttributes attributes, int rule) { mAttr = attributes; mIntProp = Integer.MIN_VALUE; mRule = rule; } /** input parameters must be valid */ - AudioMixMatchCriterion(Integer intProp, int rule) { + @VisibleForTesting + public AudioMixMatchCriterion(Integer intProp, int rule) { mAttr = null; mIntProp = intProp.intValue(); mRule = rule; } + private AudioMixMatchCriterion(@NonNull Parcel in) { + Objects.requireNonNull(in); + mRule = in.readInt(); + final int match_rule = mRule & ~RULE_EXCLUSION_MASK; + switch (match_rule) { + case RULE_MATCH_ATTRIBUTE_USAGE: + case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: + mAttr = AudioAttributes.CREATOR.createFromParcel(in); + mIntProp = Integer.MIN_VALUE; + break; + case RULE_MATCH_UID: + case RULE_MATCH_USERID: + case RULE_MATCH_AUDIO_SESSION_ID: + mIntProp = in.readInt(); + mAttr = null; + break; + default: + // assume there was in int value to read as for now they come in pair + in.readInt(); + throw new IllegalArgumentException( + "Illegal rule value " + mRule + " in parcel"); + } + } + @Override public int hashCode() { return Objects.hash(mAttr, mIntProp, mRule); @@ -170,7 +199,13 @@ public class AudioMixingRule { && Objects.equals(mAttr, other.mAttr); } - void writeToParcel(Parcel dest) { + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mRule); final int match_rule = mRule & ~RULE_EXCLUSION_MASK; switch (match_rule) { @@ -190,6 +225,22 @@ public class AudioMixingRule { } } + public static final @NonNull Parcelable.Creator<AudioMixMatchCriterion> CREATOR = + new Parcelable.Creator<>() { + /** + * Rebuilds an AudioMixMatchCriterion previously stored with writeToParcel(). + * + * @param p Parcel object to read the AudioMix from + * @return a new AudioMixMatchCriterion created from the data in the parcel + */ + public AudioMixMatchCriterion createFromParcel(Parcel p) { + return new AudioMixMatchCriterion(p); + } + public AudioMixMatchCriterion[] newArray(int size) { + return new AudioMixMatchCriterion[size]; + } + }; + public AudioAttributes getAudioAttributes() { return mAttr; } public int getIntProp() { return mIntProp; } public int getRule() { return mRule; } @@ -605,13 +656,14 @@ public class AudioMixingRule { if (!(property instanceof AudioAttributes)) { throw new IllegalArgumentException("Invalid AudioAttributes argument"); } - return addRuleInternal((AudioAttributes) property, null, rule); + return addRuleInternal( + new AudioMixMatchCriterion((AudioAttributes) property, rule)); } else { // implies integer match rule if (!(property instanceof Integer)) { throw new IllegalArgumentException("Invalid Integer argument"); } - return addRuleInternal(null, (Integer) property, rule); + return addRuleInternal(new AudioMixMatchCriterion((Integer) property, rule)); } } @@ -636,12 +688,13 @@ public class AudioMixingRule { * @return the same Builder instance. * @throws IllegalArgumentException */ - private Builder addRuleInternal(AudioAttributes attrToMatch, Integer intProp, int rule) + private Builder addRuleInternal(AudioMixMatchCriterion criterion) throws IllegalArgumentException { // If mix type is invalid and added rule is valid only for the players / recorders, // adjust the mix type accordingly. // Otherwise, if the mix type was already deduced or set explicitly, verify the rule // is valid for the mix type. + final int rule = criterion.mRule; if (mTargetMixType == AudioMix.MIX_TYPE_INVALID) { if (isPlayerRule(rule)) { mTargetMixType = AudioMix.MIX_TYPE_PLAYERS; @@ -655,51 +708,16 @@ public class AudioMixingRule { } synchronized (mCriteria) { int oppositeRule = rule ^ RULE_EXCLUSION_MASK; - if (mCriteria.stream().anyMatch(criterion -> criterion.mRule == oppositeRule)) { + if (mCriteria.stream().anyMatch( + otherCriterion -> otherCriterion.mRule == oppositeRule)) { throw new IllegalArgumentException("AudioMixingRule cannot contain RULE_MATCH_*" + " and RULE_EXCLUDE_* for the same dimension."); } - int ruleWithoutExclusion = rule & ~RULE_EXCLUSION_MASK; - switch (ruleWithoutExclusion) { - case RULE_MATCH_ATTRIBUTE_USAGE: - case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: - mCriteria.add(new AudioMixMatchCriterion(attrToMatch, rule)); - break; - case RULE_MATCH_UID: - case RULE_MATCH_USERID: - case RULE_MATCH_AUDIO_SESSION_ID: - mCriteria.add(new AudioMixMatchCriterion(intProp, rule)); - break; - default: - throw new IllegalStateException("Unreachable code in addRuleInternal()"); - } + mCriteria.add(criterion); } return this; } - Builder addRuleFromParcel(Parcel in) throws IllegalArgumentException { - final int rule = in.readInt(); - final int match_rule = rule & ~RULE_EXCLUSION_MASK; - AudioAttributes attr = null; - Integer intProp = null; - switch (match_rule) { - case RULE_MATCH_ATTRIBUTE_USAGE: - case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: - attr = AudioAttributes.CREATOR.createFromParcel(in); - break; - case RULE_MATCH_UID: - case RULE_MATCH_USERID: - case RULE_MATCH_AUDIO_SESSION_ID: - intProp = new Integer(in.readInt()); - break; - default: - // assume there was in int value to read as for now they come in pair - in.readInt(); - throw new IllegalArgumentException("Illegal rule value " + rule + " in parcel"); - } - return addRuleInternal(attr, intProp, rule); - } - /** * Combines all of the matching and exclusion rules that have been set and return a new * {@link AudioMixingRule} object. @@ -717,4 +735,52 @@ public class AudioMixingRule { mVoiceCommunicationCaptureAllowed); } } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + // write opt-out respect + dest.writeBoolean(mAllowPrivilegedPlaybackCapture); + // write voice communication capture allowed flag + dest.writeBoolean(mVoiceCommunicationCaptureAllowed); + // write specified mix type + dest.writeInt(mTargetMixType); + // write mix rules + dest.writeInt(mCriteria.size()); + for (AudioMixingRule.AudioMixMatchCriterion criterion : mCriteria) { + criterion.writeToParcel(dest, flags); + } + } + + public static final @NonNull Parcelable.Creator<AudioMixingRule> CREATOR = + new Parcelable.Creator<>() { + + @Override + public AudioMixingRule createFromParcel(Parcel source) { + AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder(); + // read opt-out respect + ruleBuilder.allowPrivilegedPlaybackCapture(source.readBoolean()); + // read voice capture allowed flag + ruleBuilder.voiceCommunicationCaptureAllowed(source.readBoolean()); + // read specified mix type + ruleBuilder.setTargetMixRole(source.readInt()); + // read mix rules + int nbRules = source.readInt(); + for (int j = 0; j < nbRules; j++) { + // read the matching rules + ruleBuilder.addRuleInternal( + AudioMixMatchCriterion.CREATOR.createFromParcel(source)); + } + return ruleBuilder.build(); + } + + @Override + public AudioMixingRule[] newArray(int size) { + return new AudioMixingRule[size]; + } + }; } diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 3e5de821b47d..e9a6ed4dcf08 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -44,6 +44,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; +import android.util.Pair; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -408,6 +409,39 @@ public class AudioPolicy { } /** + * Update {@link AudioMixingRule}-s of already registered {@link AudioMix}-es. + * + * @param mixingRuleUpdates - {@link List} of {@link Pair}-s, each pair containing + * {@link AudioMix} to update and its new corresponding {@link AudioMixingRule}. + * + * @return {@link AudioManager#SUCCESS} if the update was successful, + * {@link AudioManager#ERROR} otherwise. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public int updateMixingRules( + @NonNull List<Pair<AudioMix, AudioMixingRule>> mixingRuleUpdates) { + Objects.requireNonNull(mixingRuleUpdates); + + IAudioService service = getService(); + try { + synchronized (mLock) { + final int status = service.updateMixingRulesForPolicy( + mixingRuleUpdates.stream().map(p -> p.first).toArray(AudioMix[]::new), + mixingRuleUpdates.stream().map(p -> p.second).toArray( + AudioMixingRule[]::new), + cb()); + if (status == AudioManager.SUCCESS) { + mConfig.updateMixingRules(mixingRuleUpdates); + } + return status; + } + } catch (RemoteException e) { + Log.e(TAG, "Received remote exeception in updateMixingRules call: ", e); + return AudioManager.ERROR; + } + } + + /** * @hide * Configures the audio framework so that all audio streams originating from the given UID * can only come from a set of audio devices. diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java index 7a85d21bf144..d277c7dfbea4 100644 --- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java +++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java @@ -17,16 +17,17 @@ package android.media.audiopolicy; import android.annotation.NonNull; -import android.media.AudioFormat; import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; +import android.util.Pair; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -85,72 +86,20 @@ public class AudioPolicyConfig implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mMixes.size()); for (AudioMix mix : mMixes) { - // write mix route flags - dest.writeInt(mix.getRouteFlags()); - // write callback flags - dest.writeInt(mix.mCallbackFlags); - // write device information - dest.writeInt(mix.mDeviceSystemType); - dest.writeString(mix.mDeviceAddress); - // write mix format - dest.writeInt(mix.getFormat().getSampleRate()); - dest.writeInt(mix.getFormat().getEncoding()); - dest.writeInt(mix.getFormat().getChannelMask()); - // write opt-out respect - dest.writeBoolean(mix.getRule().allowPrivilegedMediaPlaybackCapture()); - // write voice communication capture allowed flag - dest.writeBoolean(mix.getRule().voiceCommunicationCaptureAllowed()); - // write specified mix type - dest.writeInt(mix.getRule().getTargetMixRole()); - // write mix rules - final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria(); - dest.writeInt(criteria.size()); - for (AudioMixMatchCriterion criterion : criteria) { - criterion.writeToParcel(dest); - } + mix.writeToParcel(dest, flags); } } private AudioPolicyConfig(Parcel in) { - mMixes = new ArrayList<AudioMix>(); int nbMixes = in.readInt(); + mMixes = new ArrayList<>(nbMixes); for (int i = 0 ; i < nbMixes ; i++) { - final AudioMix.Builder mixBuilder = new AudioMix.Builder(); - // read mix route flags - int routeFlags = in.readInt(); - mixBuilder.setRouteFlags(routeFlags); - // read callback flags - mixBuilder.setCallbackFlags(in.readInt()); - // read device information - mixBuilder.setDevice(in.readInt(), in.readString()); - // read mix format - int sampleRate = in.readInt(); - int encoding = in.readInt(); - int channelMask = in.readInt(); - final AudioFormat format = new AudioFormat.Builder().setSampleRate(sampleRate) - .setChannelMask(channelMask).setEncoding(encoding).build(); - mixBuilder.setFormat(format); - - AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder(); - // read opt-out respect - ruleBuilder.allowPrivilegedPlaybackCapture(in.readBoolean()); - // read voice capture allowed flag - ruleBuilder.voiceCommunicationCaptureAllowed(in.readBoolean()); - // read specified mix type - ruleBuilder.setTargetMixRole(in.readInt()); - // read mix rules - int nbRules = in.readInt(); - for (int j = 0 ; j < nbRules ; j++) { - // read the matching rules - ruleBuilder.addRuleFromParcel(in); - } - mixBuilder.setMixingRule(ruleBuilder.build()); - mMixes.add(mixBuilder.build()); + mMixes.add(AudioMix.CREATOR.createFromParcel(in)); } } - public static final @android.annotation.NonNull Parcelable.Creator<AudioPolicyConfig> CREATOR - = new Parcelable.Creator<AudioPolicyConfig>() { + public static final @android.annotation.NonNull Parcelable.Creator<AudioPolicyConfig> CREATOR = + new Parcelable.Creator<>() { /** * Rebuilds an AudioPolicyConfig previously stored with writeToParcel(). * @param p Parcel object to read the AudioPolicyConfig from @@ -309,6 +258,23 @@ public class AudioPolicyConfig implements Parcelable { } } + /** + * Update audio mixing rules for already registered {@link AudioMix}-es. + * + * @param audioMixingRuleUpdates {@link List} of {@link Pair}-s containing {@link AudioMix} to + * be updated and the new {@link AudioMixingRule}. + */ + public void updateMixingRules( + @NonNull List<Pair<AudioMix, AudioMixingRule>> audioMixingRuleUpdates) { + Objects.requireNonNull(audioMixingRuleUpdates).forEach( + update -> updateMixingRule(update.first, update.second)); + } + + private void updateMixingRule(AudioMix audioMixToUpdate, AudioMixingRule audioMixingRule) { + mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent( + mix -> mix.setAudioMixingRule(audioMixingRule)); + } + private static String mixTypeId(int type) { if (type == AudioMix.MIX_TYPE_PLAYERS) return "p"; else if (type == AudioMix.MIX_TYPE_RECORDERS) return "r"; diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixUnitTests.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixUnitTests.java deleted file mode 100644 index a26398ac198a..000000000000 --- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixUnitTests.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.audiopolicytest; - -import static android.media.AudioFormat.CHANNEL_OUT_MONO; -import static android.media.AudioFormat.CHANNEL_OUT_STEREO; -import static android.media.AudioFormat.ENCODING_PCM_16BIT; -import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_INJECTOR; -import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_PLAYERS; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_AUDIO_SESSION_ID; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_UID; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; - -import android.media.AudioFormat; -import android.media.AudioSystem; -import android.media.audiopolicy.AudioMix; -import android.media.audiopolicy.AudioMixingRule; -import android.media.audiopolicy.AudioPolicyConfig; -import android.os.Parcel; -import android.platform.test.annotations.Presubmit; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.google.common.testing.EqualsTester; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -/** - * Unit tests for AudioMix. - * - * Run with "atest AudioMixUnitTests". - */ -@Presubmit -@RunWith(AndroidJUnit4.class) -public class AudioMixUnitTests { - private static final AudioFormat OUTPUT_FORMAT_STEREO_44KHZ_PCM = - new AudioFormat.Builder() - .setSampleRate(44000) - .setChannelMask(CHANNEL_OUT_STEREO) - .setEncoding(ENCODING_PCM_16BIT).build(); - private static final AudioFormat OUTPUT_FORMAT_MONO_16KHZ_PCM = - new AudioFormat.Builder() - .setSampleRate(16000) - .setChannelMask(CHANNEL_OUT_MONO) - .setEncoding(ENCODING_PCM_16BIT).build(); - private static final AudioFormat INPUT_FORMAT_MONO_16KHZ_PCM = - new AudioFormat.Builder() - .setSampleRate(16000) - .setChannelMask(AudioFormat.CHANNEL_IN_MONO) - .setEncoding(ENCODING_PCM_16BIT).build(); - - @Test - public void testEquals() { - final EqualsTester equalsTester = new EqualsTester(); - - // --- Equality group 1 - final AudioMix playbackAudioMixWithSessionId42AndUid123 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, 42) - .addMixRule(RULE_MATCH_UID, 123).build()) - .setFormat(OUTPUT_FORMAT_STEREO_44KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - final AudioMix playbackAudioMixWithUid123AndSessionId42 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 123) - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, 42).build()) - .setFormat(OUTPUT_FORMAT_STEREO_44KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - equalsTester.addEqualityGroup( - playbackAudioMixWithSessionId42AndUid123, - playbackAudioMixWithUid123AndSessionId42, - writeToAndFromParcel(playbackAudioMixWithSessionId42AndUid123), - writeToAndFromParcel(playbackAudioMixWithUid123AndSessionId42)); - - // --- Equality group 2 - final AudioMix recordingAudioMixWithSessionId42AndUid123 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_INJECTOR) - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, 42) - .addMixRule(RULE_MATCH_UID, 123).build()) - .setFormat(INPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - final AudioMix recordingAudioMixWithUid123AndSessionId42 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_INJECTOR) - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, 42) - .addMixRule(RULE_MATCH_UID, 123).build()) - .setFormat(INPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - equalsTester.addEqualityGroup(recordingAudioMixWithSessionId42AndUid123, - recordingAudioMixWithUid123AndSessionId42, - writeToAndFromParcel(recordingAudioMixWithSessionId42AndUid123), - writeToAndFromParcel(recordingAudioMixWithUid123AndSessionId42)); - - // --- Equality group 3 - final AudioMix recordingAudioMixWithSessionId42AndUid123Render = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, 42) - .addMixRule(RULE_MATCH_UID, 123).build()) - .setFormat(INPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags( - AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER).build(); - equalsTester.addEqualityGroup(recordingAudioMixWithSessionId42AndUid123Render, - writeToAndFromParcel(recordingAudioMixWithSessionId42AndUid123Render)); - - // --- Equality group 4 - final AudioMix playbackAudioMixWithUid123 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 123).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - equalsTester.addEqualityGroup(playbackAudioMixWithUid123, - writeToAndFromParcel(playbackAudioMixWithUid123)); - - // --- Equality group 5 - final AudioMix playbackAudioMixWithUid42 = - new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - equalsTester.addEqualityGroup(playbackAudioMixWithUid42, - writeToAndFromParcel(playbackAudioMixWithUid42)); - - equalsTester.testEquals(); - } - - @Test - public void buildRenderToRemoteSubmix_success() { - final String deviceAddress = "address"; - final AudioMix audioMix = new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER) - .setDevice(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, /*address=*/deviceAddress).build(); - - assertEquals(deviceAddress, audioMix.getRegistration()); - assertEquals(OUTPUT_FORMAT_MONO_16KHZ_PCM, audioMix.getFormat()); - assertEquals(AudioMix.ROUTE_FLAG_RENDER, audioMix.getRouteFlags()); - } - - @Test - public void buildLoopbackAndRenderToRemoteSubmix_success() { - final String deviceAddress = "address"; - final AudioMix audioMix = new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER) - .setDevice(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, /*address=*/deviceAddress).build(); - - assertEquals(deviceAddress, audioMix.getRegistration()); - assertEquals(OUTPUT_FORMAT_MONO_16KHZ_PCM, audioMix.getFormat()); - assertEquals(AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER, audioMix.getRouteFlags()); - } - - @Test - public void buildRenderToSpeaker_success() { - final AudioMix audioMix = new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER) - .setDevice(AudioSystem.DEVICE_OUT_SPEAKER, /*address=*/"").build(); - - assertEquals(OUTPUT_FORMAT_MONO_16KHZ_PCM, audioMix.getFormat()); - assertEquals(AudioMix.ROUTE_FLAG_RENDER, audioMix.getRouteFlags()); - } - - @Test - public void buildLoopbackForPlayerMix_success() { - final AudioMix audioMix = new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - - assertEquals(OUTPUT_FORMAT_MONO_16KHZ_PCM, audioMix.getFormat()); - assertEquals(AudioMix.ROUTE_FLAG_LOOP_BACK, audioMix.getRouteFlags()); - } - - @Test - public void buildLoopbackForInjectorMix_success() { - final AudioMix audioMix = new AudioMix.Builder(new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_INJECTOR) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK).build(); - - assertEquals(OUTPUT_FORMAT_MONO_16KHZ_PCM, audioMix.getFormat()); - assertEquals(AudioMix.ROUTE_FLAG_LOOP_BACK, audioMix.getRouteFlags()); - } - - @Test - public void buildLoopbackWithIncompatibleDevice_throws() { - assertThrows(IllegalArgumentException.class, () -> new AudioMix.Builder( - new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK) - .setDevice(AudioSystem.DEVICE_OUT_SPEAKER, /*address=*/"").build()); - } - - @Test - public void buildRenderWithoutDevice_throws() { - assertThrows(IllegalArgumentException.class, () -> new AudioMix.Builder( - new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER).build()); - } - - @Test - public void buildRenderWithInputDevice_throws() { - assertThrows(IllegalArgumentException.class, () -> new AudioMix.Builder( - new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_PLAYERS) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER) - .setDevice(AudioSystem.DEVICE_IN_BUILTIN_MIC, /*address=*/"").build()); - } - - @Test - public void buildRenderWithInjectorMix_throws() { - assertThrows(IllegalArgumentException.class, () -> new AudioMix.Builder( - new AudioMixingRule.Builder() - .setTargetMixRole(MIX_ROLE_INJECTOR) - .addMixRule(RULE_MATCH_UID, 42).build()) - .setFormat(OUTPUT_FORMAT_MONO_16KHZ_PCM) - .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER) - .setDevice(AudioSystem.DEVICE_OUT_SPEAKER, /*address=*/"").build()); - } - - - - private static AudioMix writeToAndFromParcel(AudioMix audioMix) { - AudioPolicyConfig apc = new AudioPolicyConfig(new ArrayList<>(List.of(audioMix))); - Parcel parcel = Parcel.obtain(); - apc.writeToParcel(parcel, /*flags=*/0); - parcel.setDataPosition(0); - AudioMix unmarshalledMix = - AudioPolicyConfig.CREATOR.createFromParcel(parcel).getMixes().get(0); - parcel.recycle(); - return unmarshalledMix; - } -} diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java deleted file mode 100644 index 3cbfd50ff859..000000000000 --- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioMixingRuleUnitTests.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.audiopolicytest; - -import static android.media.AudioAttributes.USAGE_MEDIA; -import static android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION; -import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_INJECTOR; -import static android.media.audiopolicy.AudioMixingRule.MIX_ROLE_PLAYERS; -import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET; -import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE; -import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_AUDIO_SESSION_ID; -import static android.media.audiopolicy.AudioMixingRule.RULE_EXCLUDE_UID; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_AUDIO_SESSION_ID; -import static android.media.audiopolicy.AudioMixingRule.RULE_MATCH_UID; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.collection.IsCollectionWithSize.hasSize; -import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; - - -import android.media.AudioAttributes; -import android.media.audiopolicy.AudioMixingRule; -import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion; -import android.platform.test.annotations.Presubmit; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.hamcrest.CustomTypeSafeMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Unit tests for AudioPolicy. - * - * Run with "atest AudioMixingRuleUnitTests". - */ -@Presubmit -@RunWith(AndroidJUnit4.class) -public class AudioMixingRuleUnitTests { - private static final AudioAttributes USAGE_MEDIA_AUDIO_ATTRIBUTES = - new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build(); - private static final AudioAttributes CAPTURE_PRESET_VOICE_RECOGNITION_AUDIO_ATTRIBUTES = - new AudioAttributes.Builder().setCapturePreset(VOICE_RECOGNITION).build(); - private static final int TEST_UID = 42; - private static final int OTHER_UID = 77; - private static final int TEST_SESSION_ID = 1234; - - @Test - public void testConstructValidRule() { - AudioMixingRule rule = new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .addMixRule(RULE_MATCH_UID, TEST_UID) - .excludeMixRule(RULE_MATCH_AUDIO_SESSION_ID, TEST_SESSION_ID) - .build(); - - // Based on the rules, the mix type should fall back to MIX_ROLE_PLAYERS, - // since the rules are valid for both MIX_ROLE_PLAYERS & MIX_ROLE_INJECTOR. - assertEquals(rule.getTargetMixRole(), MIX_ROLE_PLAYERS); - assertThat(rule.getCriteria(), containsInAnyOrder( - isAudioMixMatchUsageCriterion(USAGE_MEDIA), - isAudioMixMatchUidCriterion(TEST_UID), - isAudioMixExcludeSessionCriterion(TEST_SESSION_ID))); - } - - @Test - public void testConstructRuleWithConflictingCriteriaFails() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .addMixRule(RULE_MATCH_UID, TEST_UID) - // Conflicts with previous criterion. - .addMixRule(RULE_EXCLUDE_UID, OTHER_UID) - .build()); - } - - @Test - public void testRuleBuilderDedupsCriteria() { - AudioMixingRule rule = new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .addMixRule(RULE_MATCH_UID, TEST_UID) - // Identical to previous criterion. - .addMixRule(RULE_MATCH_UID, TEST_UID) - // Identical to first criterion. - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .build(); - - assertThat(rule.getCriteria(), hasSize(2)); - assertThat(rule.getCriteria(), containsInAnyOrder( - isAudioMixMatchUsageCriterion(USAGE_MEDIA), - isAudioMixMatchUidCriterion(TEST_UID))); - } - - @Test - public void failsWhenAddAttributeRuleCalledWithInvalidType() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - // Rule match attribute usage requires AudioAttributes, not - // just the int enum value of the usage. - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA) - .build()); - } - - @Test - public void failsWhenExcludeAttributeRuleCalledWithInvalidType() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - // Rule match attribute usage requires AudioAttributes, not - // just the int enum value of the usage. - .excludeMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA) - .build()); - } - - @Test - public void failsWhenAddIntRuleCalledWithInvalidType() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - // Rule match uid requires Integer not AudioAttributes. - .addMixRule(RULE_MATCH_UID, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .build()); - } - - @Test - public void failsWhenExcludeIntRuleCalledWithInvalidType() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - // Rule match uid requires Integer not AudioAttributes. - .excludeMixRule(RULE_MATCH_UID, USAGE_MEDIA_AUDIO_ATTRIBUTES) - .build()); - } - - @Test - public void injectorMixTypeDeductionWithGenericRuleSucceeds() { - AudioMixingRule rule = new AudioMixingRule.Builder() - // UID rule can be used both with MIX_ROLE_PLAYERS and MIX_ROLE_INJECTOR. - .addMixRule(RULE_MATCH_UID, TEST_UID) - // Capture preset rule is only valid for injector, MIX_ROLE_INJECTOR should - // be deduced. - .addMixRule(RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET, - CAPTURE_PRESET_VOICE_RECOGNITION_AUDIO_ATTRIBUTES) - .build(); - - assertEquals(rule.getTargetMixRole(), MIX_ROLE_INJECTOR); - assertThat(rule.getCriteria(), containsInAnyOrder( - isAudioMixMatchUidCriterion(TEST_UID), - isAudioMixMatchCapturePresetCriterion(VOICE_RECOGNITION))); - } - - @Test - public void settingTheMixTypeToIncompatibleInjectorMixFails() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET, - CAPTURE_PRESET_VOICE_RECOGNITION_AUDIO_ATTRIBUTES) - // Capture preset cannot be defined for MIX_ROLE_PLAYERS. - .setTargetMixRole(MIX_ROLE_PLAYERS) - .build()); - } - - @Test - public void addingPlayersOnlyRuleWithInjectorsOnlyRuleFails() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder() - // MIX_ROLE_PLAYERS only rule. - .addMixRule(RULE_MATCH_ATTRIBUTE_USAGE, USAGE_MEDIA_AUDIO_ATTRIBUTES) - // MIX ROLE_INJECTOR only rule. - .addMixRule(RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET, - CAPTURE_PRESET_VOICE_RECOGNITION_AUDIO_ATTRIBUTES) - .build()); - } - - @Test - public void sessionIdRuleCompatibleWithPlayersMix() { - int sessionId = 42; - AudioMixingRule rule = new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, sessionId) - .setTargetMixRole(MIX_ROLE_PLAYERS) - .build(); - - assertEquals(rule.getTargetMixRole(), MIX_ROLE_PLAYERS); - assertThat(rule.getCriteria(), containsInAnyOrder(isAudioMixSessionCriterion(sessionId))); - } - - @Test - public void sessionIdRuleCompatibleWithInjectorMix() { - AudioMixingRule rule = new AudioMixingRule.Builder() - .addMixRule(RULE_MATCH_AUDIO_SESSION_ID, TEST_SESSION_ID) - .setTargetMixRole(MIX_ROLE_INJECTOR) - .build(); - - assertEquals(rule.getTargetMixRole(), MIX_ROLE_INJECTOR); - assertThat(rule.getCriteria(), - containsInAnyOrder(isAudioMixSessionCriterion(TEST_SESSION_ID))); - } - - @Test - public void audioMixingRuleWithNoRulesFails() { - assertThrows(IllegalArgumentException.class, - () -> new AudioMixingRule.Builder().build()); - } - - - private static Matcher isAudioMixUidCriterion(int uid, boolean exclude) { - return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("uid mix criterion") { - @Override - public boolean matchesSafely(AudioMixMatchCriterion item) { - int expectedRule = exclude ? RULE_EXCLUDE_UID : RULE_MATCH_UID; - return item.getRule() == expectedRule && item.getIntProp() == uid; - } - - @Override - public void describeMismatchSafely( - AudioMixMatchCriterion item, Description mismatchDescription) { - mismatchDescription.appendText( - String.format("is not %s criterion with uid %d", - exclude ? "exclude" : "match", uid)); - } - }; - } - - private static Matcher isAudioMixMatchUidCriterion(int uid) { - return isAudioMixUidCriterion(uid, /*exclude=*/ false); - } - - private static Matcher isAudioMixCapturePresetCriterion(int audioSource, boolean exclude) { - return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("uid mix criterion") { - @Override - public boolean matchesSafely(AudioMixMatchCriterion item) { - int expectedRule = exclude - ? RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET - : RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET; - AudioAttributes attributes = item.getAudioAttributes(); - return item.getRule() == expectedRule - && attributes != null && attributes.getCapturePreset() == audioSource; - } - - @Override - public void describeMismatchSafely( - AudioMixMatchCriterion item, Description mismatchDescription) { - mismatchDescription.appendText( - String.format("is not %s criterion with capture preset %d", - exclude ? "exclude" : "match", audioSource)); - } - }; - } - - private static Matcher isAudioMixMatchCapturePresetCriterion(int audioSource) { - return isAudioMixCapturePresetCriterion(audioSource, /*exclude=*/ false); - } - - private static Matcher isAudioMixUsageCriterion(int usage, boolean exclude) { - return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("usage mix criterion") { - @Override - public boolean matchesSafely(AudioMixMatchCriterion item) { - int expectedRule = - exclude ? RULE_EXCLUDE_ATTRIBUTE_USAGE : RULE_MATCH_ATTRIBUTE_USAGE; - AudioAttributes attributes = item.getAudioAttributes(); - return item.getRule() == expectedRule - && attributes != null && attributes.getUsage() == usage; - } - - @Override - public void describeMismatchSafely( - AudioMixMatchCriterion item, Description mismatchDescription) { - mismatchDescription.appendText( - String.format("is not %s criterion with usage %d", - exclude ? "exclude" : "match", usage)); - } - }; - } - - private static Matcher isAudioMixMatchUsageCriterion(int usage) { - return isAudioMixUsageCriterion(usage, /*exclude=*/ false); - } - - private static Matcher isAudioMixSessionCriterion(int sessionId, boolean exclude) { - return new CustomTypeSafeMatcher<AudioMixMatchCriterion>("sessionId mix criterion") { - @Override - public boolean matchesSafely(AudioMixMatchCriterion item) { - int excludeRule = - exclude ? RULE_EXCLUDE_AUDIO_SESSION_ID : RULE_MATCH_AUDIO_SESSION_ID; - return item.getRule() == excludeRule && item.getIntProp() == sessionId; - } - - @Override - public void describeMismatchSafely( - AudioMixMatchCriterion item, Description mismatchDescription) { - mismatchDescription.appendText( - String.format("is not %s criterion with session id %d", - exclude ? "exclude" : "match", sessionId)); - } - }; - } - - private static Matcher isAudioMixSessionCriterion(int sessionId) { - return isAudioMixSessionCriterion(sessionId, /*exclude=*/ false); - } - - private static Matcher isAudioMixExcludeSessionCriterion(int sessionId) { - return isAudioMixSessionCriterion(sessionId, /*exclude=*/ true); - } - -} diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml index cb01f2d0d9ac..5d491dba2e9e 100644 --- a/packages/CompanionDeviceManager/res/values-th/strings.xml +++ b/packages/CompanionDeviceManager/res/values-th/strings.xml @@ -26,7 +26,7 @@ <string name="profile_name_glasses" msgid="3506504967216601277">"อุปกรณ์"</string> <string name="summary_glasses" msgid="2872254734959842579">"แอปนี้จะได้รับสิทธิ์ดังต่อไปนี้ใน<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ของคุณ"</string> <string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string> - <string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string> + <string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการข้ามอุปกรณ์"</string> <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string> <string name="title_automotive_projection" msgid="3296005598978412847"></string> <string name="summary_automotive_projection" msgid="8683801274662496164"></string> diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml index 4d97803f4dbb..8d06765099a9 100644 --- a/packages/CredentialManager/res/values-el/strings.xml +++ b/packages/CredentialManager/res/values-el/strings.xml @@ -53,7 +53,7 @@ <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Θέλετε να αποθηκεύσετε τον κωδικό πρόσβασης σε κάποια άλλη συσκευή;"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Θέλετε να αποθηκεύσετε τα στοιχεία σύνδεσης σε κάποια άλλη συσκευή;"</string> <string name="use_provider_for_all_title" msgid="4201020195058980757">"Να χρησιμοποιηθεί το <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> για όλες τις συνδέσεις σας;"</string> - <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτός ο διαχειριστής κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς πρόσβασης και τα κλειδιά πρόσβασης, για πιο εύκολη πρόσβαση"</string> + <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτός ο διαχειριστής κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς και τα κλειδιά πρόσβασης, για πιο εύκολη σύνδεση"</string> <string name="set_as_default" msgid="4415328591568654603">"Ορισμός ως προεπιλογής"</string> <string name="settings" msgid="6536394145760913145">"Ρυθμίσεις"</string> <string name="use_once" msgid="9027366575315399714">"Χρήση μία φορά"</string> diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml index 88afea4d1641..a6e0d3d11eee 100644 --- a/packages/CredentialManager/res/values-fa/strings.xml +++ b/packages/CredentialManager/res/values-fa/strings.xml @@ -56,7 +56,7 @@ <string name="use_provider_for_all_description" msgid="1998772715863958997">"این مدیر گذرواژه برای <xliff:g id="USERNAME">%1$s</xliff:g> گذرکلیدها و گذرواژههای شما را ذخیره میکند تا بهراحتی بتوانید به سیستم وارد شوید"</string> <string name="set_as_default" msgid="4415328591568654603">"تنظیم بهعنوان پیشفرض"</string> <string name="settings" msgid="6536394145760913145">"تنظیمات"</string> - <string name="use_once" msgid="9027366575315399714">"یکبار استفاده"</string> + <string name="use_once" msgid="9027366575315399714">"این بار استفاده شود"</string> <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> گذرواژه • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> گذرکلید"</string> <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> گذرواژه"</string> <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> گذرکلید"</string> diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml index d986a935fad4..05d21e013d27 100644 --- a/packages/CredentialManager/res/values-hi/strings.xml +++ b/packages/CredentialManager/res/values-hi/strings.xml @@ -56,7 +56,7 @@ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए यह पासवर्ड मैनेजर, आपके पासवर्ड और पासकी सेव करेगा, ताकि आपको साइन इन करने में आसानी हो"</string> <string name="set_as_default" msgid="4415328591568654603">"डिफ़ॉल्ट के तौर पर सेट करें"</string> <string name="settings" msgid="6536394145760913145">"सेटिंग"</string> - <string name="use_once" msgid="9027366575315399714">"इसका इस्तेमाल एक बार किया जा सकता है"</string> + <string name="use_once" msgid="9027366575315399714">"एक बार इस्तेमाल करें"</string> <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> पासवर्ड • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> पासकी"</string> <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> पासवर्ड"</string> <string name="more_options_usage_passkeys" msgid="5390320437243042237">"<xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g> पासकी"</string> diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml index b597a9a227eb..ed42f3afcfe0 100644 --- a/packages/CredentialManager/res/values-ka/strings.xml +++ b/packages/CredentialManager/res/values-ka/strings.xml @@ -52,7 +52,7 @@ <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"გსურთ სხვა მოწყობილობაზე წვდომის გასაღებების შექმნა?"</string> <string name="save_password_on_other_device_title" msgid="5829084591948321207">"გსურთ სხვა მოწყობილობაზე პაროლის შენახვა?"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"გსურთ სხვა მოწყობილობაზე ავტორიზაციის მონაცემების შენახვა?"</string> - <string name="use_provider_for_all_title" msgid="4201020195058980757">"გსურთ, გამოიყენოთ<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> სისტემაში ყველა შესვლისთვის?"</string> + <string name="use_provider_for_all_title" msgid="4201020195058980757">"გსურთ, გამოიყენოთ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> სისტემაში ყველა შესვლისთვის?"</string> <string name="use_provider_for_all_description" msgid="1998772715863958997">"მოცემული პაროლების მმართველი <xliff:g id="USERNAME">%1$s</xliff:g>-ისთვის შეინახავს თქვენს პაროლებს და წვდომის გასაღებს, რომლებიც დაგეხმარებათ სისტემაში მარტივად შესვლაში"</string> <string name="set_as_default" msgid="4415328591568654603">"ნაგულისხმევად დაყენება"</string> <string name="settings" msgid="6536394145760913145">"პარამეტრები"</string> diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml index ae680a068933..7447ab629f72 100644 --- a/packages/CredentialManager/res/values-kn/strings.xml +++ b/packages/CredentialManager/res/values-kn/strings.xml @@ -52,7 +52,7 @@ <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"ಇನ್ನೊಂದು ಸಾಧನದಲ್ಲಿ ಪಾಸ್ಕೀ ಅನ್ನು ರಚಿಸಬೇಕೆ?"</string> <string name="save_password_on_other_device_title" msgid="5829084591948321207">"ಇನ್ನೊಂದು ಸಾಧನದಲ್ಲಿ ಪಾಸ್ವರ್ಡ್ ಉಳಿಸಬೇಕೆ?"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"ಮತ್ತೊಂದು ಸಾಧನದಲ್ಲಿ ಸೈನ್-ಇನ್ ಅನ್ನು ಉಳಿಸಬೇಕೆ?"</string> - <string name="use_provider_for_all_title" msgid="4201020195058980757">"ನಿಮ್ಮ ಎಲ್ಲಾ ಸೈನ್-ಇನ್ಗಳಿಗಾಗಿ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸುವುದೇ?"</string> + <string name="use_provider_for_all_title" msgid="4201020195058980757">"ನಿಮ್ಮ ಎಲ್ಲಾ ಸೈನ್-ಇನ್ಗಳಿಗಾಗಿ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಬೇಕೇ?"</string> <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> ಗಾಗಿ ಈ ಪಾಸ್ವರ್ಡ್ ನಿರ್ವಾಹಕವು ನಿಮಗೆ ಸುಲಭವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡುವುದಕ್ಕೆ ಸಹಾಯ ಮಾಡಲು ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ಗಳು ಮತ್ತು ಪಾಸ್ಕೀಗಳನ್ನು ಸಂಗ್ರಹಿಸುತ್ತದೆ"</string> <string name="set_as_default" msgid="4415328591568654603">"ಡೀಫಾಲ್ಟ್ ಆಗಿ ಸೆಟ್ ಮಾಡಿ"</string> <string name="settings" msgid="6536394145760913145">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml index d5f5f7f10578..c3b941bfa10e 100644 --- a/packages/CredentialManager/res/values-lt/strings.xml +++ b/packages/CredentialManager/res/values-lt/strings.xml @@ -52,7 +52,7 @@ <string name="create_passkey_in_other_device_title" msgid="2360053098931886245">"Sukurti „passkey“ kitame įrenginyje?"</string> <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Išsaugoti slaptažodį kitame įrenginyje?"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Išsaugoti prisijungimo duomenis kitame įrenginyje?"</string> - <string name="use_provider_for_all_title" msgid="4201020195058980757">"Naudoti <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> visada prisijungiant?"</string> + <string name="use_provider_for_all_title" msgid="4201020195058980757">"Naudoti „<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>“ visada prisijungiant?"</string> <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir prieigos raktai, kad galėtumėte lengvai prisijungti"</string> <string name="set_as_default" msgid="4415328591568654603">"Nustatyti kaip numatytąjį"</string> <string name="settings" msgid="6536394145760913145">"Nustatymai"</string> diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml index 0755c9cdfa48..1f456bfd392f 100644 --- a/packages/CredentialManager/res/values-mk/strings.xml +++ b/packages/CredentialManager/res/values-mk/strings.xml @@ -56,7 +56,7 @@ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Овој управник со лозинки за <xliff:g id="USERNAME">%1$s</xliff:g> ќе ги складира вашите лозинки и криптографски клучеви за да ви помогне лесно да се најавите"</string> <string name="set_as_default" msgid="4415328591568654603">"Постави како стандардна опција"</string> <string name="settings" msgid="6536394145760913145">"Поставки"</string> - <string name="use_once" msgid="9027366575315399714">"Употребете еднаш"</string> + <string name="use_once" msgid="9027366575315399714">"Употреби го еднаш"</string> <string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Лозинки: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string> <string name="more_options_usage_passwords" msgid="1632047277723187813">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> лозинки"</string> <string name="more_options_usage_passkeys" msgid="5390320437243042237">"Криптографски клучеви: <xliff:g id="PASSKEYSNUMBER">%1$s</xliff:g>"</string> diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml index 8168b5178f80..90805a40e002 100644 --- a/packages/CredentialManager/res/values-sk/strings.xml +++ b/packages/CredentialManager/res/values-sk/strings.xml @@ -53,7 +53,7 @@ <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Chcete uložiť heslo v inom zariadení?"</string> <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Chcete uložiť prihlasovacie údaje v inom zariadení?"</string> <string name="use_provider_for_all_title" msgid="4201020195058980757">"Chcete pre všetky svoje prihlasovacie údaje použiť <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string> - <string name="use_provider_for_all_description" msgid="1998772715863958997">"Tento správca hesiel poskytovateľa <xliff:g id="USERNAME">%1$s</xliff:g> uchová vaše heslá a prístupové kľúče, aby vám pomohol ľahšie sa prihlasovať"</string> + <string name="use_provider_for_all_description" msgid="1998772715863958997">"Tento správca hesiel pre účet <xliff:g id="USERNAME">%1$s</xliff:g> bude uchovávať vaše heslá a prístupové kľúče, aby ste sa mohli ľahšie prihlasovať"</string> <string name="set_as_default" msgid="4415328591568654603">"Nastaviť ako predvolené"</string> <string name="settings" msgid="6536394145760913145">"Nastavenia"</string> <string name="use_once" msgid="9027366575315399714">"Použiť raz"</string> diff --git a/packages/EncryptedLocalTransport/Android.bp b/packages/EncryptedLocalTransport/Android.bp index 09e563076c95..9ae6d9648979 100644 --- a/packages/EncryptedLocalTransport/Android.bp +++ b/packages/EncryptedLocalTransport/Android.bp @@ -27,9 +27,6 @@ android_app { name: "EncryptedLocalTransport", defaults: ["platform_app_defaults"], srcs: ["src/**/*.java"], - optimize: { - proguard_flags_files: ["proguard.flags"], - }, static_libs: ["LocalTransport"], platform_apis: true, certificate: "platform", diff --git a/packages/EncryptedLocalTransport/proguard.flags b/packages/EncryptedLocalTransport/proguard.flags deleted file mode 100644 index e4ce3c524e35..000000000000 --- a/packages/EncryptedLocalTransport/proguard.flags +++ /dev/null @@ -1,2 +0,0 @@ --keep class com.android.localTransport.EncryptedLocalTransport --keep class com.android.localTransport.EncryptedLocalTransportService diff --git a/packages/Keyguard/proguard.flags b/packages/Keyguard/proguard.flags deleted file mode 100644 index fb74b64cb92b..000000000000 --- a/packages/Keyguard/proguard.flags +++ /dev/null @@ -1,27 +0,0 @@ --keep public class * { - public void setBackgroundAlpha(float); - public float getBackgroundAlpha(); - public void setContentAlpha(float); - public float getContentAlpha(); - public void setAlpha(float); - public float getAlpha(); - public void setAlpha(int); - public int getAlpha(); - public void setRotationX(float); - public float getRotationX(); - public void setRotationY(float); - public float getRotationY(); - public void setPivotX(float); - public float getPivotX(); - public void setPivotY(float); - public float getPivotY(); - public void setScaleX(float); - public float getScaleX(); - public void setScaleY(float); - public float getScaleY(); - public void setTranslationX(float); - public float getTranslationX(); - public void setTranslationY(float); - public float getTranslationY(); -} - diff --git a/packages/LocalTransport/Android.bp b/packages/LocalTransport/Android.bp index d4fa1915a140..e7a273b83a7d 100644 --- a/packages/LocalTransport/Android.bp +++ b/packages/LocalTransport/Android.bp @@ -27,9 +27,7 @@ android_app { name: "LocalTransport", defaults: ["platform_app_defaults"], srcs: ["src/**/*.java"], - optimize: { - proguard_flags_files: ["proguard.flags"], - }, + libs: ["keepanno-annotations"], platform_apis: true, certificate: "platform", privileged: true, diff --git a/packages/LocalTransport/proguard.flags b/packages/LocalTransport/proguard.flags deleted file mode 100644 index c1f51b892d40..000000000000 --- a/packages/LocalTransport/proguard.flags +++ /dev/null @@ -1,5 +0,0 @@ --keep class com.android.localTransport.LocalTransport --keep class com.android.localTransport.LocalTransportParameters --keep class com.android.localTransport.LocalTransportService - - diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java index 73f87302dd05..933be11bfaf1 100644 --- a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java +++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java @@ -38,6 +38,9 @@ import android.util.ArrayMap; import android.util.Base64; import android.util.Log; +import com.android.tools.r8.keepanno.annotations.KeepTarget; +import com.android.tools.r8.keepanno.annotations.UsesReflection; + import libcore.io.IoUtils; import java.io.BufferedOutputStream; @@ -127,6 +130,13 @@ public class LocalTransport extends BackupTransport { return mParameters; } + + @UsesReflection({ + // As the runtime class name is used to generate the returned name, and the returned + // name may be used used with reflection, generate the necessary keep rules. + @KeepTarget(classConstant = LocalTransport.class), + @KeepTarget(extendsClassConstant = LocalTransport.class) + }) @Override public String name() { return new ComponentName(mContext, this.getClass()).flattenToShortString(); diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml index 03e3925955a7..9ee0882028a7 100644 --- a/packages/PackageInstaller/res/values-it/strings.xml +++ b/packages/PackageInstaller/res/values-it/strings.xml @@ -50,7 +50,7 @@ <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string> <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App non trovata"</string> <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Impossibile trovare l\'applicazione nell\'elenco di applicazioni installate."</string> - <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorizzate"</string> + <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorizzata"</string> <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utente corrente non è autorizzato a eseguire questa disinstallazione."</string> <string name="generic_error_dlg_title" msgid="5863195085927067752">"Errore"</string> <string name="generic_error_dlg_text" msgid="5287861443265795232">"Impossibile disinstallare l\'app."</string> diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp index 3d35bad68a73..5dcb9d2f6e77 100644 --- a/packages/SettingsLib/Android.bp +++ b/packages/SettingsLib/Android.bp @@ -8,7 +8,6 @@ package { } android_library { - name: "SettingsLib", static_libs: [ @@ -26,44 +25,20 @@ android_library { "iconloader", "WifiTrackerLibRes", - "SettingsLibHelpUtils", - "SettingsLibRestrictedLockUtils", - "SettingsLibActionBarShadow", - "SettingsLibAppPreference", - "SettingsLibSearchWidget", - "SettingsLibSettingsSpinner", - "SettingsLibIllustrationPreference", - "SettingsLibLayoutPreference", - "SettingsLibMainSwitchPreference", - "SettingsLibActionButtonsPreference", - "SettingsLibEntityHeaderWidgets", - "SettingsLibBarChartPreference", - "SettingsLibProgressBar", - "SettingsLibAdaptiveIcon", - "SettingsLibRadioButtonPreference", - "SettingsLibSelectorWithWidgetPreference", + "SettingsLibDeviceStateRotationLock", "SettingsLibDisplayUtils", - "SettingsLibUtils", "SettingsLibEmergencyNumber", - "SettingsLibTopIntroPreference", - "SettingsLibBannerMessagePreference", - "SettingsLibFooterPreference", - "SettingsLibUsageProgressBarPreference", - "SettingsLibCollapsingToolbarBaseActivity", - "SettingsLibTwoTargetPreference", - "SettingsLibSettingsTransition", - "SettingsLibButtonPreference", - "SettingsLibDeviceStateRotationLock", - "SettingsLibProfileSelector", + "SettingsLibSearchWidget", + "SettingsLibUtils", + "SettingsLibWidget", "setupdesign", "zxing-core-1.7", "androidx.room_room-runtime", "settingslib_flags_lib", - ], plugins: ["androidx.room_room-compiler-plugin"], - + use_resource_processor: true, resource_dirs: ["res"], srcs: [ @@ -72,6 +47,43 @@ android_library { ], } +// Group all the libraries with namespace "com.android.settingslib.widget", to allow SettingsLib to +// set use_resource_processor = true. +// We can remove SettingsLibWidget when all these libraries have its own namespace. +android_library { + name: "SettingsLibWidget", + visibility: ["//visibility:private"], + manifest: "AndroidManifest-SettingsLibWidget.xml", + static_libs: [ + "SettingsLibActionBarShadow", + "SettingsLibActionButtonsPreference", + "SettingsLibAdaptiveIcon", + "SettingsLibAppPreference", + "SettingsLibBannerMessagePreference", + "SettingsLibBarChartPreference", + "SettingsLibButtonPreference", + "SettingsLibCollapsingToolbarBaseActivity", + "SettingsLibEntityHeaderWidgets", + "SettingsLibFooterPreference", + "SettingsLibHelpUtils", + "SettingsLibIllustrationPreference", + "SettingsLibLayoutPreference", + "SettingsLibMainSwitchPreference", + "SettingsLibProfileSelector", + "SettingsLibProgressBar", + "SettingsLibRadioButtonPreference", + "SettingsLibRestrictedLockUtils", + "SettingsLibSelectorWithWidgetPreference", + "SettingsLibSettingsSpinner", + "SettingsLibSettingsTransition", + "SettingsLibTopIntroPreference", + "SettingsLibTwoTargetPreference", + "SettingsLibUsageProgressBarPreference", + ], + + resource_dirs: [], +} + // NOTE: Keep this module in sync with ./common.mk java_defaults { name: "SettingsLibDefaults", diff --git a/packages/SettingsLib/AndroidManifest-SettingsLibWidget.xml b/packages/SettingsLib/AndroidManifest-SettingsLibWidget.xml new file mode 100644 index 000000000000..38a7d6ace1f8 --- /dev/null +++ b/packages/SettingsLib/AndroidManifest-SettingsLibWidget.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2023 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest package="com.android.settingslib.widget" /> diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 8e4c6a43701d..9b82c13ce21b 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak die groottes van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktiveer vormvrye vensters"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktiveer steun vir eksperimentele vormvrye vensters."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Rekenaarmodus"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Werkskerm-rugsteunwagwoord"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volle rekenaarrugsteune word nie tans beskerm nie"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 6011eb1630ad..bd025ec8950e 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"የዝርዝር ሰነድ እሴቶች ምንም ይሁኑ ምን ለበርካታ መስኮቶች ሁሉንም እንቅስቃሴዎች መጠናቸው የሚቀየሩ እንዲሆኑ ያደርጋቸዋል።"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"የነጻ ቅርጽ መስኮቶችን ያንቁ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"የሙከራ ነፃ መልክ መስኮቶች ድጋፍን አንቃ"</string> - <string name="desktop_mode" msgid="2389067840550544462">"የዴስክቶፕ ሁነታ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"የዴስክቶፕ መጠባበቂያ ይለፍ ቃል"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ዴስክቶፕ ሙሉ ምትኬዎች በአሁኑ ሰዓት አልተጠበቁም"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"የዴስክቶፕ ሙሉ ምትኬዎች የይለፍ ቃሉን ለመለወጥ ወይም ለማስወገድ ነካ ያድርጉ"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 40c92e57c660..f5ab801a4c9e 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"السماح بتغيير حجم جميع الأنشطة لتناسب تعدد النوافذ، بغض النظر عن قيم البيان"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"تفعيل النوافذ الحرة"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"إتاحة استخدام النوافذ الحرة التجريبية"</string> - <string name="desktop_mode" msgid="2389067840550544462">"وضع سطح المكتب"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"كلمة مرور احتياطية للكمبيوتر"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string> diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml index ef72afcd40a3..a0a52b5ec262 100644 --- a/packages/SettingsLib/res/values-as/strings.xml +++ b/packages/SettingsLib/res/values-as/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"মেনিফেষ্টৰ মান যিয়েই নহওক, মাল্টি-ৱিণ্ডৰ বাবে আটাইবোৰ কাৰ্যকলাপৰ আকাৰ সলনি কৰিব পৰা কৰক।"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্ৰিফৰ্ম ৱিণ্ড\'জ সক্ষম কৰক"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পৰীক্ষামূলক ফ্ৰী-ফৰ্ম ৱিণ্ড’বোৰৰ বাবে সহায়তা সক্ষম কৰক৷"</string> - <string name="desktop_mode" msgid="2389067840550544462">"ডেস্কটপ ম’ড"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ বেকআপ পাছৱৰ্ড"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপৰ পূৰ্ণ বেকআপ এতিয়ালৈকে সংৰক্ষিত অৱস্থাত নাই"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপ সম্পূৰ্ণ বেকআপৰ বাবে পাছৱৰ্ডটো সলনি কৰিবলৈ বা আঁতৰাবলৈ টিপক"</string> diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml index a76f8ba83698..cb515bfa9234 100644 --- a/packages/SettingsLib/res/values-az/strings.xml +++ b/packages/SettingsLib/res/values-az/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest dəyərindən asılı olmayaraq çoxpəncərəli rejimdə pəncərə ölçüsünün dəyişdirilməsinə icazə verilsin"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"İxtiyari formada pəncərə yaradılsın"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Eksperimental olaraq ixtiyari formada pəncərə yaradılsın"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Masaüstü rejimi"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü rezerv parolu"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam rezervlər hazırda qorunmayıblar."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstünün tam rezerv kopyalanması üçün parolu dəyişmək və ya silmək üçün basın"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 4d7a5fe897f6..011967493a0e 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore proizvoljnog formata"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Režim za računare"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka rezervne kopije za računar"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string> diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml index f46adf8dc649..b46debff8c66 100644 --- a/packages/SettingsLib/res/values-be/strings.xml +++ b/packages/SettingsLib/res/values-be/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Зрабіць усе віды дзейнасці даступнымі для змены памеру ў рэжыме некалькіх вокнаў, незалежна ад значэнняў маніфеста."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Уключыць адвольную форму вокнаў"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Уключыць падтрымку для эксперыментальнай адвольнай формы акна."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Рэжым працоўнага стала"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для рэз. копіі ПК"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Поўнае рэзервовае капіраванне працоўнага стала зараз не абаронена"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Краніце, каб змяніць або выдаліць пароль для поўнага рэзервовага капіравання працоўнага стала"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index fa3cba2eb0a7..592f6178e74d 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Дава възможност за преоразмеряване на всички активности в режима за няколко прозореца независимо от стойностите в манифеста."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Активиране на прозорците в свободна форма"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Активиране на поддръжката за експерименталните прозорци в свободна форма."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Режим за компютри"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Парола за резервни копия"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Понастоящем пълните резервни копия за настолен компютър не са защитени"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Докоснете, за да промените или премахнете паролата за пълни резервни копия на настолния компютър"</string> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index d3dc359f11d7..3fafee31d634 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ম্যানিফেস্ট মানগুলির নির্বিশেষে মাল্টি-উইন্ডোর জন্য সমস্ত ক্রিয়াকলাপগুলির আকার পরিবর্তনযোগ্য করুন৷"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্রি-ফর্ম উইন্ডো চালু করুন"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string> - <string name="desktop_mode" msgid="2389067840550544462">"\'ডেস্কটপ\' মোড"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ ব্যাকআপ পাসওয়ার্ড"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপ পূর্ণ ব্যাকআপ বর্তমানে সুরক্ষিত নয়"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপের সম্পূর্ণ ব্যাকআপের পাসওয়ার্ডটি পরিবর্তন করতে বা মুছে ফেলতে আলতো চাপুন"</string> diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index 0487e29cb401..5f7bd2c3cfa5 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava mijenjanje veličine svih aktivnosti za prikaz s više prozora, bez obzira na prikazane vrijednosti"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore nepravilnih oblika"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore nepravilnih oblika."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Način rada radne površine"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka sigurnosne kopije za računar"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije s radne površine"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 62938eb9c677..7143f99207c9 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet ajustar la mida de totes les activitats per al mode multifinestra, independentment dels valors del manifest"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Activa les finestres amb format lliure"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa la compatibilitat amb finestres experimentals amb format lliure"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Mode d\'escriptori"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Contrasenya per a còpies d\'ordinador"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les còpies de seguretat completes d\'ordinador no estan protegides"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca per canviar o suprimir la contrasenya per a les còpies de seguretat completes de l\'ordinador"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index d6aa84e2a6fe..34e65e63c8e8 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožní změnu velikosti všech aktivit na několik oken (bez ohledu na hodnoty manifestu)"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivovat okna s volným tvarem"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivuje podporu experimentálních oken s volným tvarem"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Režim počítače"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pro zálohy v počítači"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nejsou v současné době chráněny"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tuto možnost vyberte, chcete-li změnit nebo odebrat heslo pro úplné zálohy do počítače"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index d1b02227f75a..381c3cc630ea 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tillad, at alle aktiviteter kan tilpasses flere vinduer uafhængigt af manifestværdier"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivér vinduer i frit format"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivér understøttelse af eksperimentelle vinduer i frit format"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Computertilstand"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Kode til lokal backup"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Lokale komplette backups er i øjeblikket ikke beskyttet"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal backup"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index a74374a2e10f..b53d19181148 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Die Größe aller Aktivitäten darf, ungeachtet der Manifestwerte, für die Mehrfensterdarstellung angepasst werden"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Freiform-Fenster zulassen"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Unterstützung für experimentelle Freiform-Fenster aktivieren"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktopmodus"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Passwort für Desktop-Sicherung"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Vollständige Desktop-Sicherungen sind momentan nicht passwortgeschützt"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Zum Ändern oder Entfernen des Passworts für vollständige Desktop-Sicherungen tippen"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 9f000bbcb2eb..b4cc7aa2630e 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Να έχουν όλες οι δραστηριότητες δυνατότητα αλλαγής μεγέθους για την προβολή πολλαπλών παραθύρων, ανεξάρτητα από τις τιμές του μανιφέστου."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ενεργοποίηση παραθύρων ελεύθερης μορφής"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Λειτ. επιφάνειας εργασίας"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Εφ/κός κωδικός desktop"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτήν τη στιγμή"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Πατήστε για αλλαγή ή κατάργηση του κωδικού πρόσβασης για τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 5bb58d1fe2b5..9fd825bf4e7f 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string> diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml index 5b1e86f1ccc7..546e5d238f54 100644 --- a/packages/SettingsLib/res/values-en-rCA/strings.xml +++ b/packages/SettingsLib/res/values-en-rCA/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizable for multi-window, regardless of manifest values."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren’t currently protected"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 5bb58d1fe2b5..9fd825bf4e7f 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 5bb58d1fe2b5..9fd825bf4e7f 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string> diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml index 8f4ba0ee077f..8256cc953794 100644 --- a/packages/SettingsLib/res/values-en-rXC/strings.xml +++ b/packages/SettingsLib/res/values-en-rXC/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizable for multi-window, regardless of manifest values."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren’t currently protected"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 9015ed5a916f..ff9f7aeba4bf 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permitir que todas las actividades puedan cambiar de tamaño para el modo multiventana, sin importar los valores del manifiesto."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modo de escritorio"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Contraseñas"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tus copias de seguridad de escritorio no están protegidas por contraseña."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Presiona para cambiar o quitar la contraseña de las copias de seguridad completas de tu escritorio."</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 4ee27537119d..abf60d8386ed 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite que todas las actividades puedan cambiar de tamaño en multiventana independientemente de los valores de manifiesto"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modo Escritorio"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Contraseña para copias de ordenador"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Las copias de seguridad completas de ordenador no están protegidas"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar o quitar la contraseña de las copias de seguridad completas del escritorio"</string> diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml index 466746619e6f..4e70a53e4727 100644 --- a/packages/SettingsLib/res/values-et/strings.xml +++ b/packages/SettingsLib/res/values-et/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Muudetakse kõigi tegevuste suurused mitme aknaga vaates muudetavaks (manifesti väärtustest olenemata)."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Luba vabas vormis aknad"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Lubatakse katseliste vabavormis akende tugi."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Lauaarvuti režiim"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Arvutivarunduse parool"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Täielikud arvutivarundused pole praegu kaitstud"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Puudutage täielike arvutivarunduste parooli muutmiseks või eemaldamiseks"</string> diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml index d9c4ee7c5ec1..8dd60071ad54 100644 --- a/packages/SettingsLib/res/values-eu/strings.xml +++ b/packages/SettingsLib/res/values-eu/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Eman aukera jarduera guztien tamaina doitzeko, hainbat leihotan erabili ahal izan daitezen, ezarritako balioak kontuan izan gabe"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Gaitu estilo libreko leihoak"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Onartu estilo libreko leiho esperimentalak"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Ordenagailuetarako modua"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Babeskopien pasahitz lokala"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Une honetan, ordenagailuko babeskopia osoak ez daude babestuta"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ordenagailuko eduki guztiaren babeskopia egiteko erabiltzen den pasahitza aldatzeko edo kentzeko, sakatu hau"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 1d538648369e..beaaa3922557 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"بدون توجه به مقادیر مانیفست، اندازه همه فعالیتها برای حالت چند پنجرهای میتواند تغییر کند."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"فعال کردن پنجرههای آزاد"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"فعال کردن پشتیبانی برای پنجرههای آزاد آزمایشی."</string> - <string name="desktop_mode" msgid="2389067840550544462">"حالت رایانه"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"گذرواژه پشتیبانگیری محلی"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"پشتیبانگیری کامل رایانه درحال حاضر محافظت نمیشود"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخههای پشتیبان کامل رایانهای ضربه بزنید"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 579771b986d9..ec1c1f1843dd 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pakota kaikki toiminnot hyväksymään koon muuttaminen usean ikkunan tilassa luettelon arvoista riippumatta"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ota käyttöön vapaamuotoiset ikkunat"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ota kokeellisten vapaamuotoisten ikkunoiden tuki käyttöön"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Työpöytätila"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Varmuuskop. salasana"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tietokoneen kaikkien tietojen varmuuskopiointia ei ole tällä hetkellä suojattu"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Vaihda tai poista tietokoneen kaikkien tietojen varmuuskopioinnin salasana koskettamalla."</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index f3c92e16276a..f48bfcb4eb75 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet de redimensionner toutes les activités pour le mode multi-fenêtre, indépendamment des valeurs du fichier manifeste."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Mode Bureau"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe sauvegarde PC"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Touchez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur ordinateur."</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 8e84b0b5ed52..ca5edfe44227 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendre toutes les activités redimensionnables pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Mode ordinateur"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe de sauvegarde ordi"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur ordi ne sont actuellement pas protégées"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Appuyez pour modifier ou supprimer le mot de passe des sauvegardes complètes sur ordi."</string> diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml index d78ab179b737..61b01f63e687 100644 --- a/packages/SettingsLib/res/values-gl/strings.xml +++ b/packages/SettingsLib/res/values-gl/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite axustar o tamaño de todas as actividades para o modo multiventá, independentemente dos valores do manifesto"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Activar ventás de forma libre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa a compatibilidade con ventás de forma libre experimentais"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modo de escritorio"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Contrasinal para copias"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"As copias de seguranza de ordenador completas non están protexidas"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar ou quitar o contrasinal para as copias de seguranza completas de ordenador"</string> diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml index 2301bfd887c2..981cf57d734e 100644 --- a/packages/SettingsLib/res/values-gu/strings.xml +++ b/packages/SettingsLib/res/values-gu/strings.xml @@ -174,7 +174,7 @@ <string name="launch_defaults_some" msgid="3631650616557252926">"કેટલાંક ડિફોલ્ટ્સ સેટ કરેલ છે"</string> <string name="launch_defaults_none" msgid="8049374306261262709">"કોઈ ડિફૉલ્ટ સેટ કરેલા નથી"</string> <string name="tts_settings" msgid="8130616705989351312">"ટેક્સ્ટ ટૂ સ્પીચ સેટિંગ"</string> - <string name="tts_settings_title" msgid="7602210956640483039">"ટેક્સ્ટ ટુ સ્પીચ આઉટપુટ"</string> + <string name="tts_settings_title" msgid="7602210956640483039">"ટેક્સ્ટ ટૂ સ્પીચ આઉટપુટ"</string> <string name="tts_default_rate_title" msgid="3964187817364304022">"સ્પીચ રેટ"</string> <string name="tts_default_rate_summary" msgid="3781937042151716987">"ટેક્સ્ટ બોલાયેલ છે તે ઝડપ"</string> <string name="tts_default_pitch_title" msgid="6988592215554485479">"પિચ"</string> @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"મૅનિફેસ્ટ મૂલ્યોને ધ્યાનમાં લીધા સિવાય, તમામ પ્રવૃત્તિઓને મલ્ટી-વિન્ડો માટે ફરીથી કદ બદલી શકે તેવી બનાવો."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"પ્રાયોગિક ફ્રીફોર્મ વિન્ડો માટે સપોર્ટને ચાલુ કરો."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ડેસ્કટૉપ મોડ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ડેસ્કટૉપ બૅકઅપ પાસવર્ડ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ડેસ્કટૉપ સંપૂર્ણ બૅકઅપ હાલમાં સુરક્ષિત નથી"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ્સ માટેનો પાસવર્ડ બદલવા અથવા દૂર કરવા માટે ટૅચ કરો"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 363793c2a8ce..9be1cd68b789 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"सभी गतिविधियों को मल्टी-विंडो (एक से ज़्यादा ऐप्लिकेशन, एक साथ) के लिए साइज़ बदलने लायक बनाएं, चाहे उनकी मेनिफ़ेस्ट वैल्यू कुछ भी हो."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"फ़्रीफ़ॉर्म विंडो (एक साथ कई विंडो दिखाना) चालू करें"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"फ़्रीफ़ॉर्म विंडो आज़माने की सुविधा चालू करें."</string> - <string name="desktop_mode" msgid="2389067840550544462">"डेस्कटॉप मोड"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटॉप बैकअप पासवर्ड"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्कटॉप का पूरा बैकअप फ़िलहाल सुरक्षित नहीं है"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉप के पूरे बैक अप का पासवर्ड बदलने या हटाने के लिए टैप करें"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 8be767609dc5..8a0114a0d636 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogući mijenjanje veličine svih aktivnosti za više prozora, neovisno o vrijednostima manifesta."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore slobodnog oblika"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućuje podršku za eksperimentalne prozore slobodnog oblika."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Stolni način rada"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Zaporka sigurnosne kopije"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije na stolnom računalu trenutačno nisu zaštićene"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promijenili ili uklonili zaporku za potpune sigurnosne kopije na računalu"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 6885a07cc71e..b5e1e01587b5 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Legyen az összes tevékenység átméretezhető a többablakos megjelenítés érdekében a jegyzékértékektől függetlenül."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Szabad formájú ablakok engedélyezése"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Kísérleti, szabad formájú ablakok támogatásának engedélyezése."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Asztali üzemmód"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Asztali mentés jelszava"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Az asztali teljes biztonsági mentések jelenleg nem védettek."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Koppintson ide az asztali teljes mentések jelszavának módosításához vagy eltávolításához"</string> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index c77769e83cf0..9808f709fdcb 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Բոլոր ակտիվությունների չափերը բազմապատուհան ռեժիմի համար դարձնել փոփոխելի՝ մանիֆեստի արժեքներից անկախ:"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ակտիվացնել կամայական ձևի պատուհանները"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Միացնել ազատ ձևի փորձնական պատուհանների աջակցումը:"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Համակարգչի ռեժիմ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Աշխատասեղանի պահուստավորման գաղտնաբառ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Աշխատասեղանի ամբողջական պահուստավորումները այժմ պաշտպանված չեն"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Հպեք՝ աշխատասեղանի ամբողջական պահուստավորման գաղտնաբառը փոխելու կամ հեռացնելու համար"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 2168e8fd8482..7d70b88844ba 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Membuat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktifkan jendela berformat bebas"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Mode desktop"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Sandi cadangan desktop"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Saat ini cadangan desktop penuh tidak dilindungi"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string> diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml index 46eb90c93312..650f76d990f4 100644 --- a/packages/SettingsLib/res/values-is/strings.xml +++ b/packages/SettingsLib/res/values-is/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gera stærð allrar virkni breytanlega svo að hún henti fyrir marga glugga, óháð gildum í upplýsingaskrá."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Virkja glugga með frjálsu sniði"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Virkja stuðning við glugga með frjálsu sniði á tilraunastigi."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Skjáborðsstilling"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Aðgangsorð tölvuafritunar"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Heildarafritun á tölvu er ekki varin sem stendur."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ýttu til að breyta eða fjarlægja aðgangsorðið fyrir heildarafritun á tölvu"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index bbe04122f033..d783bf1b4e71 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Attiva finestre a forma libera"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Attiva il supporto delle finestre a forma libera sperimentali"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modalità desktop"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Password di backup desktop"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"I backup desktop completi non sono attualmente protetti"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocca per modificare o rimuovere la password per i backup desktop completi"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 85e3a53dbfb1..fc83630c30cb 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"מאפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא התחשבות בערכי המניפסט."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"הפעלת האפשרות לשנות את הגודל והמיקום של החלונות"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"הפעלת תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ממשק המחשב"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"סיסמת גיבוי שולחן העבודה"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"יש להקיש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 71e70ba9ed5e..3f090830de40 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"マニフェストの値に関係なく、マルチウィンドウですべてのアクティビティのサイズを変更できるようにします。"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"フリーフォーム ウィンドウを有効にする"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"試験運用機能のフリーフォーム ウィンドウのサポートを有効にします。"</string> - <string name="desktop_mode" msgid="2389067840550544462">"デスクトップ モード"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"PC バックアップ パスワード"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"デスクトップのフルバックアップは現在保護されていません"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"デスクトップのフルバックアップ用のパスワードを変更または削除する場合にタップします"</string> diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml index fa7db4ad901d..ed7c8d7cd207 100644 --- a/packages/SettingsLib/res/values-ka/strings.xml +++ b/packages/SettingsLib/res/values-ka/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"მანიფესტის მნიშვნელობების მიუხედავად, მრავალი ფანჯრის რეჟიმისთვის ყველა აქტივობის ზომაცვლადად გადაქცევა."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"თავისუფალი ფორმის მქონე ფანჯრების ჩართვა"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტული ფუნქციის ჩართვა."</string> - <string name="desktop_mode" msgid="2389067840550544462">"დესკტოპის რეჟიმი"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"დესკტოპის სარეზერვო ასლის პაროლი"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"დესკტოპის სრული სარეზერვო ასლები ამჟამად დაცული არ არის"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"შეეხეთ დესკტოპის სრული სარეზერვო ასლების პაროლის შესაცვლელად ან წასაშლელად"</string> diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml index efac4e830270..982000f68852 100644 --- a/packages/SettingsLib/res/values-kk/strings.xml +++ b/packages/SettingsLib/res/values-kk/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Манифест мәндеріне қарамастан, бірнеше терезе режимінде барлық әрекеттердің өлшемін өзгертуге рұқсат беру"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Еркін пішінді терезелерге рұқсат беру"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Еркін пішінді терезелерді құру эксперименттік функиясын қосу"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Компьютер режимі"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Компьютердегі сақтық көшірме құпия сөзі"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютердегі толық сақтық көшірмелер қазір қорғалмаған."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Үстелдік компьютердің толық сақтық көшірмелерінің кілтсөзін өзгерту немесе жою үшін түртіңіз"</string> diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml index 11c71cac8158..26bb1e27661c 100644 --- a/packages/SettingsLib/res/values-km/strings.xml +++ b/packages/SettingsLib/res/values-km/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ធ្វើឲ្យសកម្មភាពទាំងអស់អាចប្តូរទំហំបានសម្រាប់ពហុវិនដូ ដោយមិនគិតពីតម្លៃមេនីហ្វេសថ៍។"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"បើកដំណើរការផ្ទាំងវិនដូទម្រង់សេរី"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"បើកឱ្យអាចប្រើផ្ទាំងវិនដូទម្រង់សេរីពិសោធន៍។"</string> - <string name="desktop_mode" msgid="2389067840550544462">"មុខងារកុំព្យូទ័រ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ពាក្យសម្ងាត់បម្រុងទុកលើកុំព្យូទ័រ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"បច្ចុប្បន្ន ការបម្រុងទុកពេញលេញនៅលើកុំព្យូទ័រមិនត្រូវបានការពារទេ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ប៉ះដើម្បីប្ដូរ ឬយកពាក្យសម្ងាត់ចេញសម្រាប់ការបម្រុងទុកពេញលេញលើកុំព្យូទ័រ"</string> diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml index fa3dbaf3a0d6..5a09396480e7 100644 --- a/packages/SettingsLib/res/values-kn/strings.xml +++ b/packages/SettingsLib/res/values-kn/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ಮ್ಯಾನಿಫೆಸ್ಟ್ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಗಣಿಸದೇ, ಬಹು-ವಿಂಡೊಗೆ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಗಳನ್ನು ಮರುಗಾತ್ರಗೊಳಿಸುವಂತೆ ಮಾಡಿ."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ಪ್ರಾಯೋಗಿಕ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ಡೆಸ್ಕ್ಟಾಪ್ ಮೋಡ್"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ಡೆಸ್ಕ್ಟಾಪ್ ಬ್ಯಾಕಪ್ ಪಾಸ್ವರ್ಡ್"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ಡೆಸ್ಕ್ಟಾಪ್ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ಡೆಸ್ಕ್ಟಾಪ್ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್ಗಳಿಗೆ ಪಾಸ್ವರ್ಡ್ ಬದಲಾಯಿಸಲು ಅಥವಾ ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index f4841338ec6d..1c5fd76ad7b6 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"모든 활동을 매니페스트 값에 관계없이 멀티 윈도우용으로 크기 조정 가능하도록 설정"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"자유 형식 창 사용"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"자유 형식 창 지원 사용"</string> - <string name="desktop_mode" msgid="2389067840550544462">"데스크톱 모드"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"데스크톱 백업 비밀번호"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"데스크톱 전체 백업에 비밀번호가 설정되어 있지 않음"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"데스크톱 전체 백업에 대한 비밀번호를 변경하거나 삭제하려면 탭하세요."</string> diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml index bde9b08cf716..4ad4306286bd 100644 --- a/packages/SettingsLib/res/values-ky/strings.xml +++ b/packages/SettingsLib/res/values-ky/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Бир нече терезе режиминде өлчөмдү өзгөртүүгө уруксат берет (манифесттин маанилерине карабастан)"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Эркин формадагы терезелерди түзүүнү иштетүү"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Эркин формадагы терезелерди түзүү боюнча сынамык функциясы иштетилет."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Компьютер режими"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Камдык көчүрмөнүн сырсөзү"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Толук камдык көчүрмөлөр учурда корголгон эмес"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Иш тактасынын камдалган сырсөзүн өзгөртүү же алып салуу үчүн таптап коюңуз"</string> diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml index 2f4e7ff6dd5e..fe8b4db7db09 100644 --- a/packages/SettingsLib/res/values-lo/strings.xml +++ b/packages/SettingsLib/res/values-lo/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ເຮັດໃຫ້ທຸກການເຄື່ອນໄຫວສາມາດປັບຂະໜາດໄດ້ສຳລັບຫຼາຍໜ້າຈໍ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ເປີດໃຊ້ໜ້າຈໍຮູບແບບອິດສະຫຼະ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ເປີດໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບທົດລອງ."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ໂໝດເດັສທັອບ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນເດັສທັອບ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັສທັອບຍັງບໍ່ໄດ້ຮັບການປ້ອງກັນໃນເວລານີ້"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ແຕະເພື່ອປ່ຽນ ຫຼື ລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັສທັອບ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 59ab47b7b0d4..e4546e1db323 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Nustatyti, kad visus veiksmus būtų galima atlikti kelių dydžių languose, nepaisant aprašo verčių."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Įgalinti laisvos formos langus"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Įgalinti eksperimentinių laisvos formos langų palaikymą."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Stalinio komp. režimas"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Viet. atsrg. kop. slapt."</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Šiuo metu visos vietinės atsarginės kopijos neapsaugotos"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Jei norite pakeisti ar pašalinti visų stalinio kompiuterio atsarginių kopijų slaptažodį, palieskite"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index a04bd54094de..e9410a20ba5a 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pielāgot visas darbības vairāku logu režīmam neatkarīgi no vērtībām manifestā."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Iespējot brīvās formas logus"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Iespējot eksperimentālo brīvās formas logu atbalstu."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Darbvirsmas režīms"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Datora dublējuma parole"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Darbvirsmas pilnie dublējumi pašlaik nav aizsargāti."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Pieskarieties, lai mainītu vai noņemtu paroli pilniem datora dublējumiem."</string> diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml index 37a448fac04e..4866e6ad8f08 100644 --- a/packages/SettingsLib/res/values-mk/strings.xml +++ b/packages/SettingsLib/res/values-mk/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Сите активности ќе имаат променлива големина во режимот со повеќе прозорци, независно од вредностите на манифестот."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Овозможи прозорци со слободна форма"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Овозможи поддршка за експериментални прозорци со слободна форма."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Режим за компјутер"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка за бекап на компјутер"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Целосниот бекап на компјутерот во моментов не е заштитен"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Допрете за да се промени или отстрани лозинката за целосен бекап на компјутерот"</string> diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml index 452a9959740d..78a3968bb0d5 100644 --- a/packages/SettingsLib/res/values-ml/strings.xml +++ b/packages/SettingsLib/res/values-ml/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"മാനിഫെസ്റ്റ് മൂല്യങ്ങൾ പരിഗണിക്കാതെ, എല്ലാ ആക്ടിവിറ്റികളെയും മൾട്ടി-വിൻഡോയ്ക്കായി വലുപ്പം മാറ്റുക."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"പരീക്ഷണാത്മക ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ഡെസ്ക്ടോപ്പ് മോഡ്"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ഡെസ്ക്ടോപ്പ് ബാക്കപ്പ് പാസ്വേഡ്"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ഡെസ്ക്ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾ നിലവിൽ പരിരക്ഷിച്ചിട്ടില്ല"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ഡെസ്ക്ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾക്കായി പാസ്വേഡുകൾ മാറ്റാനോ നീക്കംചെയ്യാനോ ടാപ്പുചെയ്യുക"</string> diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml index 6dfce5abac79..31f190ddd4fc 100644 --- a/packages/SettingsLib/res/values-mn/strings.xml +++ b/packages/SettingsLib/res/values-mn/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Тодорхойлогч файлын утгыг үл хамааран, бүх үйл ажиллагааны хэмжээг олон цонхонд өөрчилж болохуйц болгоно уу."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Туршилтын чөлөөт хэлбэрийн цонхны дэмжлэгийг идэвхжүүлнэ үү."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Дэлгэцийн горим"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Компьютерын нөөцлөлтийн нууц үг"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютерын бүрэн нөөцлөлт одоогоор хамгаалалтгүй байна"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Компьютерийн бүтэн нөөцлөлтийн нууц үгийг өөрчлөх, устгах бол дарна уу"</string> diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml index 4db523ae311f..e5852ed726f1 100644 --- a/packages/SettingsLib/res/values-mr/strings.xml +++ b/packages/SettingsLib/res/values-mr/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"मॅनिफेस्ट मूल्ये काहीही असू देत, एकाहून अधिक विंडोसाठी सर्व अॅक्टिव्हिटीचा आकार बदलण्यायोग्य करा."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"freeform windows सुरू करा"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रायोगिक freeform windows साठी सपोर्ट सुरू करा."</string> - <string name="desktop_mode" msgid="2389067840550544462">"डेस्कटॉप मोड"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटॉप बॅकअप पासवर्ड"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला पासवर्ड बदलण्यासाठी किंवा काढण्यासाठी टॅप करा"</string> diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml index ef2181298f4a..ca07d2bba3e3 100644 --- a/packages/SettingsLib/res/values-ms/strings.xml +++ b/packages/SettingsLib/res/values-ms/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bolehkan semua saiz aktiviti diubah untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Dayakan tetingkap bentuk bebas"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Dayakan sokongan untuk tetingkap bentuk bebas percubaan."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Mod desktop"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Kata laluan sandaran komputer meja"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Sandaran penuh komputer meja tidak dilindungi pada masa ini"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string> diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml index 2e4a6c451966..0b9b3d1cefc0 100644 --- a/packages/SettingsLib/res/values-my/strings.xml +++ b/packages/SettingsLib/res/values-my/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"သတ်မှတ်တန်ဖိုး မည်သို့ပင်ရှိစေ ဝင်းဒိုးများ၏ လုပ်ဆောင်မှုအားလုံးကို အရွယ်အစားပြင်သည်။"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ပုံစံမျိုးစုံ ဝင်းဒိုးများ ဖွင့်ရန်"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ပုံစံမျိုးစုံဝင်းဒိုးများ စမ်းသပ်ခြင်းအတွက် ပံ့ပိုးမှုကို ဖွင့်သည်"</string> - <string name="desktop_mode" msgid="2389067840550544462">"ဒက်စ်တော့မုဒ်"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ဒက်စ်တော့ အရန်စကားဝှက်"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ဒက်စ်တော့ အရန်သိမ်းဆည်းခြင်းအားလုံးကို လောလောဆယ် ကာကွယ်မထားပါ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ဒက်စ်တော့ အပြည့်အဝ အရန်သိမ်းခြင်းအတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index e871ab9f41e7..e68a2b78394d 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gjør at alle aktiviteter kan endre størrelse for flervindusmodus, uavhengig av manifestverdier."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Slå på vinduer i fritt format"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Slå på støtte for vinduer i eksperimentelt fritt format."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Skrivebordmodus"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Passord for sikkerhetskopiering på datamaskin"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Fullstendig sikkerhetskopiering på datamaskin er ikke beskyttet"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trykk for å endre eller fjerne passordet for fullstendige sikkerhetskopier på datamaskinen"</string> diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml index a48dd1e3ea12..e52b880a2919 100644 --- a/packages/SettingsLib/res/values-ne/strings.xml +++ b/packages/SettingsLib/res/values-ne/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"तोकिएको नियमको ख्याल नगरी एपलाई एकभन्दा बढी विन्डोमा रिसाइज गर्न सकिने बनाइयोस्।"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"फ्रिफर्म विन्डोहरू अन गरियोस्"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रयोगात्मक फ्रिफर्म विन्डोहरू चल्ने बनाइयोस्"</string> - <string name="desktop_mode" msgid="2389067840550544462">"डेस्कटप मोड"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटप ब्याकअप पासवर्ड"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"हाल डेस्कटपका सबै ब्याकअप पासवर्ड सुरक्षित छैनन्"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटप पूर्ण ब्याकअपको लागि पासवर्ड बदल्न वा हटाउन ट्याप गर्नुहोस्"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index dfc3389717a9..0d52d9d2b661 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak het formaat van alle activiteiten aanpasbaar, ongeacht de manifestwaarden"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Vensters met vrije vorm aanzetten"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Zet ondersteuning voor vensters met experimentele vrije vorm aan"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktopmodus"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Wachtwoord desktopback-up"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volledige back-ups naar desktops zijn momenteel niet beveiligd"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om het wachtwoord voor volledige back-ups naar desktops te wijzigen of te verwijderen"</string> diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml index a29fb0fb984a..eb54cba0ae41 100644 --- a/packages/SettingsLib/res/values-or/strings.xml +++ b/packages/SettingsLib/res/values-or/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ମାନିଫେଷ୍ଟ ମୂଲ୍ୟ ଯାହା ହୋଇଥାଉ ନା କାହିଁକି, ଏକାଧିକ-ୱିଣ୍ଡୋ ପାଇଁ ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ରିସାଇଜ କରନ୍ତୁ।"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋକୁ ସକ୍ଷମ କରନ୍ତୁ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ପରୀକ୍ଷାମୂଳକ ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋଗୁଡ଼ିକ ପାଇଁ ସପୋର୍ଟକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string> - <string name="desktop_mode" msgid="2389067840550544462">"ଡେସ୍କଟପ ମୋଡ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ଡେସ୍କଟପ ବେକଅପ ପାସୱାର୍ଡ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ଡେସ୍କଟପ୍ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍ଗୁଡ଼ିକ ବର୍ତ୍ତମାନ ସୁରକ୍ଷିତ ନୁହେଁ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ଡେସ୍କଟପ୍ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍ଅପ୍ ପାଇଁ ପାସ୍ୱର୍ଡ ବଦଳାଇବା କିମ୍ୱା କାଢ଼ିଦେବା ନିମନ୍ତେ ଟାପ୍ କରନ୍ତୁ"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index 917d5f8254ac..b0faa808d4ea 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ਮੈਨੀਫ਼ੈਸਟ ਮੁੱਲਾਂ ਦੀ ਪਰਵਾਹ ਕੀਤੇ ਬਿਨਾਂ, ਮਲਟੀ-ਵਿੰਡੋ ਲਈ ਸਾਰੀਆਂ ਸਰਗਰਮੀਆਂ ਨੂੰ ਆਕਾਰ ਬਦਲਣਯੋਗ ਬਣਾਓ।"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string> - <string name="desktop_mode" msgid="2389067840550544462">"ਡੈਸਕਟਾਪ ਮੋਡ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ਡੈਸਕਟਾਪ ਬੈਕਅੱਪ ਪਾਸਵਰਡ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ਡੈਸਕਟਾਪ ਦੇ ਪੂਰੇ ਬੈਕਅੱਪ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ਡੈਸਕਟਾਪ ਦੇ ਮੁਕੰਮਲ ਬੈਕਅੱਪਾਂ ਲਈ ਪਾਸਵਰਡ ਨੂੰ ਬਦਲਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 0bf5b70fc37d..cdc5ba26b37b 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Zezwalaj na zmianę rozmiaru wszystkich okien aktywności w trybie wielu okien niezależnie od ustawień w pliku manifestu"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Włącz dowolny rozmiar okien"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Tryb pulpitu"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Hasło kopii zapasowej"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Pełne kopie zapasowe na komputerze nie są obecnie chronione"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotknij, by zmienić lub usunąć hasło pełnych kopii zapasowych na komputerze."</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 9af28a6454fa..f1784bcc3c58 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modo área de trabalho"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 53221eded5f5..c510e2b63bb3 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas de forma livre experimentais."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Ambiente de trabalho"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Palavra-passe cópia do computador"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"As cópias de segurança completas no ambiente de trabalho não estão atualmente protegidas"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocar para alterar ou remover a palavra-passe para cópias de segurança completas no ambiente de trabalho"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 9af28a6454fa..f1784bcc3c58 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modo área de trabalho"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index db0993eca934..447bb63a18cc 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Activează ferestrele cu formă liberă"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activează compatibilitatea pentru ferestrele experimentale cu formă liberă."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modul desktop"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Parolă backup computer"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"În prezent, backupurile complete pe computer nu sunt protejate"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Atinge ca să modifici sau să elimini parola pentru backupurile complete pe desktop"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index e9f7b0ae7e7e..f10e8e7a144a 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Разрешить изменение размера окон в многооконном режиме (независимо от значений в манифесте)"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Разрешить создание окон произвольной формы"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Включить экспериментальную функцию создания окон произвольной формы"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Режим компьютера"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для резервного копирования"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Полные локальные резервные копии в настоящее время не защищены"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Нажмите, чтобы изменить или удалить пароль для резервного копирования"</string> diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml index d3bdd56d2889..51bd3c14d829 100644 --- a/packages/SettingsLib/res/values-si/strings.xml +++ b/packages/SettingsLib/res/values-si/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"මැනිෆෙස්ට් අගයන් නොසලකා, සියලු ක්රියාකාරකම් බහු-කවුළුව සඳහා ප්රතිප්රමාණ කළ හැකි බවට පත් කරන්න."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"අනියම් හැඩැති කවුළු සබල කරන්න"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරන්න."</string> - <string name="desktop_mode" msgid="2389067840550544462">"ඩෙස්ක්ටොප් ප්රකාරය"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ඩෙස්ක්ටොප් උපස්ථ මුරපදය"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ දැනට ආරක්ෂා කර නොමැත"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ සඳහා මුරපදය වෙනස් කිරීමට හෝ ඉවත් කිරීමට තට්ටු කරන්න"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index b34fe9d18cc6..691872842fd5 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožniť zmeniť veľkosť všetkých aktivít na niekoľko okien (bez ohľadu na hodnoty manifestu)"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Povoliť okná s voľným tvarom"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Povoliť podporu pre experimentálne okná s voľným tvarom"</string> - <string name="desktop_mode" msgid="2389067840550544462">"Režim počítača"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pre zálohy v počítači"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nie sú momentálne chránené"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Klepnutím zmeníte alebo odstránite heslo pre úplné zálohy do počítača"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index b142a6c86409..cf174e1d73f4 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsem aktivnostim spremeniti velikost za način z več okni."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Omogoči okna svobodne oblike"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogoči podporo za poskusna okna svobodne oblike."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Namizni način"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Geslo za varnostno kopijo namizja"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Popolne varnostne kopije namizja trenutno niso zaščitene."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotaknite se, če želite spremeniti ali odstraniti geslo za popolno varnostno kopiranje namizja"</string> diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml index b27b6bdd5249..7802704e4649 100644 --- a/packages/SettingsLib/res/values-sq/strings.xml +++ b/packages/SettingsLib/res/values-sq/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bëj që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivizo dritaret me formë të lirë"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Modaliteti i desktopit"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Fjalëkalimi rezervë i kompjuterit"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervimet e plota në kompjuter nuk janë të mbrojtura aktualisht"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 286e908f3314..eb10b550f97b 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Омогућава промену величине свих активности за режим са више прозора, без обзира на вредности манифеста."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Омогући прозоре произвољног формата"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Омогућава подршку за експерименталне прозоре произвољног формата."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Режим за рачунаре"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка резервне копије за рачунар"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Резервне копије читавог система тренутно нису заштићене"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index e2f7017732ec..256b4e9aacee 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gör det möjligt att ändra storleken på alla aktiviteter i flerfönsterläge, oavsett manifestvärden."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivera frihandsfönster"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivera stöd för experimentella frihandsfönster."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Datorläge"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Lösenord för säkerhetskopia av datorn"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"De fullständiga säkerhetskopiorna av datorn är för närvarande inte skyddade"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryck om du vill ändra eller ta bort lösenordet för fullständig säkerhetskopiering av datorn"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index f66684a8b233..e23dbcb314d5 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Fanya shughuli zote ziweze kubadilishwa ukubwa kwenye madirisha mengi, bila kuzingatia thamani za faili ya maelezo."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Washa madirisha yenye muundo huru"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ruhusu uwezo wa kutumia madirisha ya majaribio yenye muundo huru."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Hali ya kompyuta ya mezani"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Nenosiri la hifadhi rudufu ya eneo kazi"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Hifadhi rudufu kamili za eneo kazi hazijalindwa kwa sasa"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Gusa ili ubadilishe au uondoe nenosiri la hifadhi rudufu kamili za eneo kazi"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 22d4febc8e02..365c3dafca93 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"மேனிஃபெஸ்ட் மதிப்புகளைப் பொருட்படுத்தாமல், பல சாளரத்திற்கு எல்லா செயல்பாடுகளையும் அளவுமாறக்கூடியதாக அமை."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"குறிப்பிட்ட வடிவமில்லாத சாளரங்களை இயக்கு"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"சாளரங்களை அளவுமாற்ற மற்றும் எங்கும் நகர்த்த அனுமதிக்கும் பரிசோதனைக்குரிய அம்சத்திற்கான ஆதரவை இயக்கு."</string> - <string name="desktop_mode" msgid="2389067840550544462">"டெஸ்க்டாப் பயன்முறை"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"டெஸ்க்டாப் காப்புப்பிரதி கடவுச்சொல்"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"டெஸ்க்டாப்பின் முழு காப்புப்பிரதிகள் தற்போது பாதுகாக்கப்படவில்லை"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"டெஸ்க்டாப்பின் முழுக் காப்புப் பிரதிகளுக்கான கடவுச்சொல்லை மாற்ற அல்லது அகற்ற, தட்டவும்"</string> diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml index dc5bacd700fa..d1c464c21378 100644 --- a/packages/SettingsLib/res/values-te/strings.xml +++ b/packages/SettingsLib/res/values-te/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"మానిఫెస్ట్ విలువలతో సంబంధం లేకుండా అన్ని యాక్టివిటీస్ను పలు రకాల విండోల్లో సరిపోయేటట్లు సైజ్ మార్చగలిగేలా చేస్తుంది."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"స్వతంత్ర రూప విండోలను ఎనేబుల్ చేయండి"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ప్రయోగాత్మక స్వతంత్ర రూప విండోల కోసం సపోర్ట్ను ఎనేబుల్ చేస్తుంది."</string> - <string name="desktop_mode" msgid="2389067840550544462">"డెస్క్టాప్ మోడ్"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"డెస్క్టాప్ బ్యాకప్ పాస్వర్డ్"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"డెస్క్టాప్ పూర్తి బ్యాకప్లు ప్రస్తుతం రక్షించబడలేదు"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"డెస్క్టాప్ పూర్తి బ్యాకప్ల కోసం పాస్వర్డ్ను మార్చడానికి లేదా తీసివేయడానికి నొక్కండి"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 7dd346a9d730..bc6840bdc2d7 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ทำให้กิจกรรมทั้งหมดปรับขนาดได้สำหรับหน้าต่างหลายบาน โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"เปิดใช้หน้าต่างรูปแบบอิสระ"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"เปิดการสนับสนุนหน้าต่างรูปแบบอิสระแบบทดลอง"</string> - <string name="desktop_mode" msgid="2389067840550544462">"โหมดเดสก์ท็อป"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"รหัสผ่านการสำรองข้อมูลในเดสก์ท็อป"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"การสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อปไม่ได้รับการป้องกันในขณะนี้"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"แตะเพื่อเปลี่ยนแปลงหรือลบรหัสผ่านสำหรับการสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อป"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index 8ad8fd732b04..4360b9fa027c 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gawing nare-resize ang lahat ng aktibidad para sa multi-window, anuman ang mga value ng manifest."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"I-enable ang mga freeform window"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"I-enable ang suporta para sa mga pang-eksperimentong freeform window."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop mode"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Password ng pag-backup ng desktop"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kasalukuyang hindi pinoprotektahan ang mga buong pag-backup ng desktop"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"I-tap upang baguhin o alisin ang password para sa mga kumpletong pag-back up sa desktop"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 0af470d98433..206df8f5a8ce 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest değerlerinden bağımsız olarak, tüm etkinlikleri birden fazla pencerede yeniden boyutlandırılabilir yap."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Serbest biçimli pencereleri etkinleştir"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Deneysel serbest biçimli pencere desteğini etkinleştir."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Masaüstü modu"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü yedekleme şifresi"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam yedeklemeleri şu an korunmuyor"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstü tam yedeklemelerinin şifresini değiştirmek veya kaldırmak için dokunun"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 3b8492369fe8..2bc80df469db 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Масштабувати активність на кілька вікон, незалежно від значень у файлі маніфесту."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Увімкнути вікна довільного формату"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Увімкнути експериментальні вікна довільного формату."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Режим комп’ютера"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль рез. копії на ПК"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Повні резервні копії на комп’ютері наразі не захищені"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Торкніться, щоб змінити або видалити пароль для повного резервного копіювання на комп’ютер"</string> diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml index 9f7d18ea58f0..b8bef4c14fbb 100644 --- a/packages/SettingsLib/res/values-ur/strings.xml +++ b/packages/SettingsLib/res/values-ur/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"مینی فیسٹ اقدار سے قطع نظر، ملٹی ونڈو کیلئے تمام سرگرمیوں کو ری سائز ایبل بنائیں۔"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"freeform ونڈوز فعال کریں"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"تجرباتی فری فارم ونڈوز کیلئے سپورٹ فعال کریں۔"</string> - <string name="desktop_mode" msgid="2389067840550544462">"ڈیسک ٹاپ موڈ"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"ڈیسک ٹاپ کا بیک اپ پاس ورڈ"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ڈیسک ٹاپ کے مکمل بیک اپس فی الحال محفوظ کیے ہوئے نہیں ہیں"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ڈیسک ٹاپ کے مکمل بیک اپس کیلئے پاس ورڈ کو تبدیل کرنے یا ہٹانے کیلئے تھپتھپائیں"</string> diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml index b9c17fcafb1e..57c59e1725fe 100644 --- a/packages/SettingsLib/res/values-uz/strings.xml +++ b/packages/SettingsLib/res/values-uz/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest qiymatidan qat’i nazar barcha harakatlarni ko‘p oynali rejimga moslashtirish."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Erkin shakldagi oynalarni yoqish"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Erkin shakldagi oynalar yaratish uchun mo‘ljallangan tajribaviy funksiyani yoqish."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Desktop rejimi"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Zaxira nusxa uchun parol"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kompyuterdagi zaxira nusxalar hozirgi vaqtda himoyalanmagan"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ish stoli to‘liq zaxira nusxalari parolini o‘zgartirish yoki o‘chirish uchun bu yerni bosing"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 0eaaf219c340..9877249adca5 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Cho phép thay đổi kích thước của tất cả các hoạt động cho nhiều cửa sổ, bất kể giá trị tệp kê khai là gì."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Bật cửa sổ dạng tự do"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Bật tính năng hỗ trợ cửa sổ dạng tự do thử nghiệm."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Chế độ máy tính"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Mật khẩu cho bản sao lưu qua máy tính"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Các bản sao lưu đầy đủ qua máy tính hiện không được bảo vệ"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Nhấn để thay đổi hoặc xóa mật khẩu dành cho các bản sao lưu đầy đủ vào máy tính"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 74ab016e1e25..a210e6c02250 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"将所有 activity 设为可配合多窗口环境调整大小(无论清单值是什么)。"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"启用可自由调整的窗口"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"启用可自由调整的窗口这一实验性功能。"</string> - <string name="desktop_mode" msgid="2389067840550544462">"桌面模式"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"桌面备份密码"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面完整备份当前未设置密码保护"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"点按即可更改或移除用于保护桌面完整备份的密码"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 21f6d51540fa..f78b141eb3f9 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"在任何資訊清單值下,允許系統配合多重視窗環境調整所有活動的尺寸。"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形態視窗"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形態視窗的支援功能。"</string> - <string name="desktop_mode" msgid="2389067840550544462">"桌面模式"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"桌面電腦備份密碼"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面電腦的完整備份目前未受保護"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕按即可變更或移除桌面電腦完整備份的密碼"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 09f8d134ef94..a66a0293d25b 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"將所有活動設為可配合多重視窗環境調整大小 (無論資訊清單值為何)。"</string> <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形式視窗"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形式視窗的支援功能。"</string> - <string name="desktop_mode" msgid="2389067840550544462">"電腦模式"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"電腦備份密碼"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"目前尚未設定密碼來保護完整的備份檔案 (透過電腦備份的檔案)"</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕觸即可變更或移除電腦完整備份的密碼"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 5de118c0379f..45b8c543ad72 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -403,7 +403,6 @@ <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Yenza yonke imisebenzi ibe nosayizi abasha kumawindi amaningi, ngokunganaki amavelu e-manifest."</string> <string name="enable_freeform_support" msgid="7599125687603914253">"Nika amandla amawindi e-freeform"</string> <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Nika amandla usekelo lwe-windows yokuhlola kwe-freeform."</string> - <string name="desktop_mode" msgid="2389067840550544462">"Imodi yedeskithophu"</string> <string name="local_backup_password_title" msgid="4631017948933578709">"Iphasiwedi yokusekela ngokulondoloza ye-Desktop"</string> <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Ukusekela ngokulondoloza okugcwele kwe-Desktop akuvikelekile okwamanje."</string> <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Thepha ukushintsha noma ukususa iphasiwedi yokwenziwa kwezipele ngokugcwele kwideskithophu"</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java index af06d7304160..b1d1ea5eda42 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java @@ -126,10 +126,10 @@ public class RestrictedSwitchPreference extends SwitchPreference { switchSummary = isChecked() ? getUpdatableEnterpriseString( getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY, - R.string.enabled_by_admin) + com.android.settingslib.widget.R.string.enabled_by_admin) : getUpdatableEnterpriseString( getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY, - R.string.disabled_by_admin); + com.android.settingslib.widget.R.string.disabled_by_admin); } else { switchSummary = mRestrictedSwitchSummary; } diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index 6eb2f3834858..96bb4b586dfc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -1776,7 +1776,8 @@ public class ApplicationsState { final int userId = UserHandle.getUserId(this.info.uid); if (UserManager.get(context).isManagedProfile(userId)) { this.labelDescription = context.getString( - com.android.settingslib.R.string.accessibility_work_profile_app_description, + com.android.settingslib.utils.R + .string.accessibility_work_profile_app_description, this.label); } else { this.labelDescription = this.label; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java index cb4eba422366..f5257b070392 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BroadcastDialog.java @@ -46,7 +46,8 @@ public class BroadcastDialog extends AlertDialog { View layout = View.inflate(mContext, R.layout.broadcast_dialog, null); final Window window = getWindow(); window.setContentView(layout); - window.setWindowAnimations(R.style.Theme_AlertDialog_SettingsLib); + window.setWindowAnimations( + com.android.settingslib.widget.R.style.Theme_AlertDialog_SettingsLib); TextView title = layout.findViewById(R.id.dialog_title); TextView subTitle = layout.findViewById(R.id.dialog_subtitle); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 00397f0e646d..64c271bb7bc7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -760,6 +760,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> void onAudioModeChanged() { dispatchAttributesChanged(); } + + /** + * Notify that the audio category has changed. + */ + public void onAudioDeviceCategoryChanged() { + dispatchAttributesChanged(); + } + /** * Get the device status as active or non-active per Bluetooth profile. * diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java index 1f4cafce835f..d53c3a7aafa6 100644 --- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java @@ -153,7 +153,7 @@ public class InputMethodPreference extends PrimarySwitchPreference } final ImageView icon = holder.itemView.findViewById(android.R.id.icon); final int iconSize = getContext().getResources().getDimensionPixelSize( - R.dimen.secondary_app_icon_size); + com.android.settingslib.widget.R.dimen.secondary_app_icon_size); if (icon != null && iconSize > 0) { ViewGroup.LayoutParams params = icon.getLayoutParams(); params.height = iconSize; diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java index ebdfbeade99d..251cd3615897 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/ConversationIconFactory.java @@ -32,7 +32,6 @@ import android.util.IconDrawableFactory; import android.util.Log; import com.android.launcher3.icons.BaseIconFactory; -import com.android.settingslib.R; import com.android.settingslib.Utils; /** @@ -81,7 +80,7 @@ public class ConversationIconFactory extends BaseIconFactory { mPackageManager = pm; mIconDrawableFactory = iconDrawableFactory; mImportantConversationColor = context.getResources().getColor( - R.color.important_conversation, null); + com.android.launcher3.icons.R.color.important_conversation, null); } /** diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java index 21eb35abe32c..2d6f0587fbf7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java @@ -167,7 +167,8 @@ public class AccessPointPreference extends Preference { ImageView frictionImageView = (ImageView) view.findViewById(R.id.friction_icon); bindFrictionImage(frictionImageView); - final View divider = view.findViewById(R.id.two_target_divider); + final View divider = + view.findViewById(com.android.settingslib.widget.R.id.two_target_divider); divider.setVisibility(shouldShowDivider() ? View.VISIBLE : View.INVISIBLE); } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java index c45d77471932..015356e013b7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java @@ -331,7 +331,8 @@ public class WifiStatusTracker { return; } else if (!isDefaultNetwork && mDefaultNetworkCapabilities != null && mDefaultNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) { - statusLabel = mContext.getString(R.string.wifi_connected_low_quality); + statusLabel = mContext.getString( + com.android.wifitrackerlib.R.string.wifi_connected_low_quality); return; } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java index 74c2fc8cce4c..32a16716d9f9 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/PrimarySwitchPreferenceTest.java @@ -54,7 +54,7 @@ public class PrimarySwitchPreferenceTest { mPreference = new PrimarySwitchPreference(mContext); LayoutInflater inflater = LayoutInflater.from(mContext); mHolder = PreferenceViewHolder.createInstanceForTests(inflater.inflate( - com.android.settingslib.R.layout.preference_two_target, null)); + com.android.settingslib.widget.R.layout.preference_two_target, null)); mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame); inflater.inflate(R.layout.preference_widget_primary_switch, mWidgetView, true); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java index 06343f59e2b8..ff84dc92037f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/collapsingtoolbar/widget/CollapsingCoordinatorLayoutTest.java @@ -55,7 +55,8 @@ public class CollapsingCoordinatorLayoutTest { @Test public void onCreate_userAddedChildViewsBeMovedToContentFrame() { CollapsingCoordinatorLayout layout = mActivity.getCollapsingCoordinatorLayout(); - View contentFrameView = layout.findViewById(R.id.content_frame); + View contentFrameView = + layout.findViewById(com.android.settingslib.widget.R.id.content_frame); TextView textView = contentFrameView.findViewById(R.id.text_hello_world); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java index 471dac05e6b4..8246aff8b18e 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/lifecycle/HideNonSystemOverlayMixinTest.java @@ -29,8 +29,6 @@ import android.view.WindowManager; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import com.android.settingslib.R; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -95,7 +93,7 @@ public class HideNonSystemOverlayMixinTest { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setTheme(R.style.Theme_AppCompat); + setTheme(androidx.appcompat.R.style.Theme_AppCompat); getLifecycle().addObserver(new HideNonSystemOverlayMixin(this)); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java index 7b08fee9ac91..2f8967e34e79 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/FinancedDeviceActionDisabledByAdminControllerTest.java @@ -30,8 +30,6 @@ import android.content.Context; import androidx.test.core.app.ApplicationProvider; -import com.android.settingslib.R; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,7 +49,7 @@ public class FinancedDeviceActionDisabledByAdminControllerTest { @Before public void setUp() { - mActivity.setTheme(R.style.Theme_AppCompat_DayNight); + mActivity.setTheme(androidx.appcompat.R.style.Theme_AppCompat_DayNight); mController.initialize(mTestUtils.createLearnMoreButtonLauncher()); mController.updateEnforcedAdmin(ENFORCED_ADMIN, ENFORCEMENT_ADMIN_USER_ID); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java index 7b885660ccea..f168122994c3 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java @@ -33,8 +33,6 @@ import android.os.UserManager; import androidx.test.core.app.ApplicationProvider; -import com.android.settingslib.R; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,7 +55,7 @@ public class ManagedDeviceActionDisabledByAdminControllerTest { @Before public void setUp() { - mActivity.setTheme(R.style.Theme_AppCompat_DayNight); + mActivity.setTheme(androidx.appcompat.R.style.Theme_AppCompat_DayNight); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java index 66a2ea69559b..68312223b4b1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/CreateUserDialogControllerTest.java @@ -62,7 +62,7 @@ public class CreateUserDialogControllerTest { public void setup() { MockitoAnnotations.initMocks(this); mActivity = spy(ActivityController.of(new FragmentActivity()).get()); - mActivity.setTheme(R.style.Theme_AppCompat_DayNight); + mActivity.setTheme(androidx.appcompat.R.style.Theme_AppCompat_DayNight); mUnderTest = new TestCreateUserDialogController(); mPhotoRestrictedByBase = false; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java index f595cd334105..a95257a903e0 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java @@ -99,7 +99,7 @@ public class EditUserInfoControllerTest { public void setup() { MockitoAnnotations.initMocks(this); mActivity = spy(ActivityController.of(new FragmentActivity()).get()); - mActivity.setTheme(R.style.Theme_AppCompat_DayNight); + mActivity.setTheme(androidx.appcompat.R.style.Theme_AppCompat_DayNight); mController = new TestEditUserInfoController(); mPhotoRestrictedByBase = false; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java index 6cbae05ce9a5..10862403ae70 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveIconTest.java @@ -105,15 +105,15 @@ public class AdaptiveIconTest { icon.setBackgroundColor(mContext, tile); - assertThat(icon.mBackgroundColor) - .isEqualTo(mContext.getColor(R.color.homepage_generic_icon_background)); + assertThat(icon.mBackgroundColor).isEqualTo(mContext.getColor( + com.android.settingslib.widget.R.color.homepage_generic_icon_background)); } @Test public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() { final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, - R.color.bt_outline_color); + com.android.settingslib.widget.R.color.bt_outline_color); doReturn(Icon.createWithResource(mContext, R.drawable.ic_system_update)) .when(tile).getIcon(mContext); @@ -121,8 +121,8 @@ public class AdaptiveIconTest { new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); icon.setBackgroundColor(mContext, tile); - assertThat(icon.mBackgroundColor) - .isEqualTo(mContext.getColor(R.color.bt_outline_color)); + assertThat(icon.mBackgroundColor).isEqualTo(mContext.getColor( + com.android.settingslib.widget.R.color.bt_outline_color)); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java index 71d55bc3de2a..b2bc53dda1fa 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/AdaptiveOutlineDrawableTest.java @@ -21,8 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.content.res.Resources; import android.graphics.Paint; -import com.android.settingslib.R; - import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java index 049c90e971a9..a26f200ec603 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java @@ -58,14 +58,15 @@ public class FooterPreferenceTest { @Test public void setLearnMoreText_shouldSetAsTextInLearnMore() { final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests( - LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null)); + LayoutInflater.from(mContext) + .inflate(com.android.settingslib.widget.R.layout.preference_footer, null)); mFooterPreference.setLearnMoreText("Custom learn more"); mFooterPreference.setLearnMoreAction(view -> { /* do nothing */ } /* listener */); mFooterPreference.onBindViewHolder(holder); assertThat(((TextView) holder.findViewById( - R.id.settingslib_learn_more)).getText().toString()) + com.android.settingslib.widget.R.id.settingslib_learn_more)).getText().toString()) .isEqualTo("Custom learn more"); } @@ -94,8 +95,9 @@ public class FooterPreferenceTest { @Test public void onBindViewHolder_whenTitleIsNull_shouldNotRaiseNpe() { PreferenceViewHolder viewHolder = spy(PreferenceViewHolder.createInstanceForTests( - LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null))); - when(viewHolder.findViewById(R.id.title)).thenReturn(null); + LayoutInflater.from(mContext) + .inflate(com.android.settingslib.widget.R.layout.preference_footer, null))); + when(viewHolder.findViewById(androidx.core.R.id.title)).thenReturn(null); Throwable actualThrowable = null; try { @@ -110,8 +112,10 @@ public class FooterPreferenceTest { @Test public void onBindViewHolder_whenLearnMoreIsNull_shouldNotRaiseNpe() { PreferenceViewHolder viewHolder = spy(PreferenceViewHolder.createInstanceForTests( - LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null))); - when(viewHolder.findViewById(R.id.settingslib_learn_more)).thenReturn(null); + LayoutInflater.from(mContext) + .inflate(com.android.settingslib.widget.R.layout.preference_footer, null))); + when(viewHolder.findViewById(com.android.settingslib.widget.R.id.settingslib_learn_more)) + .thenReturn(null); Throwable actualThrowable = null; try { @@ -126,7 +130,8 @@ public class FooterPreferenceTest { @Test public void onBindViewHolder_whenIconFrameIsNull_shouldNotRaiseNpe() { PreferenceViewHolder viewHolder = spy(PreferenceViewHolder.createInstanceForTests( - LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null))); + LayoutInflater.from(mContext) + .inflate(com.android.settingslib.widget.R.layout.preference_footer, null))); when(viewHolder.findViewById(R.id.icon_frame)).thenReturn(null); Throwable actualThrowable = null; diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java index aaec909aa335..23b4c2aec80f 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/TwoTargetPreferenceTest.java @@ -32,8 +32,6 @@ import android.widget.LinearLayout; import androidx.preference.PreferenceViewHolder; -import com.android.settingslib.R; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java index 8787c2516f64..94a3173b13a1 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java @@ -165,12 +165,10 @@ public class SecureSettings { Settings.Secure.CHARGING_VIBRATION_ENABLED, Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS, Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, - Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, Settings.Secure.UI_NIGHT_MODE, Settings.Secure.UI_NIGHT_MODE_CUSTOM_TYPE, Settings.Secure.DARK_THEME_CUSTOM_START_TIME, Settings.Secure.DARK_THEME_CUSTOM_END_TIME, - Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, Settings.Secure.SKIP_DIRECTION, Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, Settings.Secure.BACK_GESTURE_INSET_SCALE_LEFT, diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java index dfc3cef48426..817999839c54 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java @@ -245,9 +245,7 @@ public class SecureSettingsValidators { Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS, NON_NEGATIVE_INTEGER_VALIDATOR); VALIDATORS.put(Secure.USER_SETUP_COMPLETE, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.ASSIST_GESTURE_SETUP_COMPLETE, BOOLEAN_VALIDATOR); - VALIDATORS.put(Secure.TRUST_AGENTS_EXTEND_UNLOCK, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, JSON_OBJECT_VALIDATOR); - VALIDATORS.put(Secure.LOCK_SCREEN_WHEN_TRUST_LOST, BOOLEAN_VALIDATOR); VALIDATORS.put(Secure.SKIP_GESTURE, BOOLEAN_VALIDATOR); /* * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled. diff --git a/packages/SharedStorageBackup/Android.bp b/packages/SharedStorageBackup/Android.bp index 21516fade1ab..225b5b4234b6 100644 --- a/packages/SharedStorageBackup/Android.bp +++ b/packages/SharedStorageBackup/Android.bp @@ -27,9 +27,6 @@ android_app { name: "SharedStorageBackup", defaults: ["platform_app_defaults"], srcs: ["src/**/*.java"], - optimize: { - proguard_flags_files: ["proguard.flags"], - }, platform_apis: true, certificate: "platform", privileged: true, diff --git a/packages/SharedStorageBackup/proguard.flags b/packages/SharedStorageBackup/proguard.flags deleted file mode 100644 index 6a66a47e3050..000000000000 --- a/packages/SharedStorageBackup/proguard.flags +++ /dev/null @@ -1,2 +0,0 @@ --keep class com.android.sharedstoragebackup.SharedStorageAgent --keep class com.android.sharedstoragebackup.ObbBackupService diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index c92fe2251f68..089ddbeda53b 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -132,20 +132,6 @@ android_library { manifest: "AndroidManifest-res.xml", } -aconfig_declarations { - name: "systemui_aconfig_flags", - package: "com.android.systemui.aconfig", - srcs: [ - "src/com/android/systemui/aconfig/systemui.aconfig", - "src/com/android/systemui/accessibility/aconfig/accessibility.aconfig", - ], -} - -java_aconfig_library { - name: "systemui_aconfig_flags_lib", - aconfig_declarations: "systemui_aconfig_flags", -} - android_library { name: "SystemUI-core", defaults: [ @@ -180,7 +166,7 @@ android_library { "SystemUISharedLib", "SystemUI-statsd", "SettingsLib", - "systemui_aconfig_flags_lib", + "com_android_systemui_flags_lib", "androidx.core_core-ktx", "androidx.viewpager2_viewpager2", "androidx.legacy_legacy-support-v4", @@ -251,6 +237,9 @@ filegroup { "tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt", "tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt", "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt", + + /* Log fakes */ + "tests/src/com/android/systemui/log/core/FakeLogBuffer.kt", ], path: "tests/src", } @@ -337,6 +326,28 @@ filegroup { "tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java", "tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt", "tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt", + + /* Communal tests */ + "tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt", + "tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt", + "tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt", + + /* Dream tests */ + "tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java", + "tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java", + "tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java", + "tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java", + "tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java", + "tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java", + "tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt", + "tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt", + "tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java", + "tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java", ], path: "tests/src", } @@ -369,7 +380,7 @@ android_library { "SystemUICustomizationLib", "SystemUI-statsd", "SettingsLib", - "systemui_aconfig_flags_lib", + "com_android_systemui_flags_lib", "androidx.viewpager2_viewpager2", "androidx.legacy_legacy-support-v4", "androidx.recyclerview_recyclerview", diff --git a/packages/SystemUI/aconfig/Android.bp b/packages/SystemUI/aconfig/Android.bp new file mode 100644 index 000000000000..c1390b252418 --- /dev/null +++ b/packages/SystemUI/aconfig/Android.bp @@ -0,0 +1,13 @@ +aconfig_declarations { + name: "com_android_systemui_flags", + package: "com.android.systemui", + srcs: [ + "systemui.aconfig", + "accessibility.aconfig", + ], +} + +java_aconfig_library { + name: "com_android_systemui_flags_lib", + aconfig_declarations: "com_android_systemui_flags", +} diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig index 91c55510608a..8841967b1535 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/aconfig/accessibility.aconfig +++ b/packages/SystemUI/aconfig/accessibility.aconfig @@ -1,7 +1,8 @@ -package: "com.android.systemui.aconfig" +package: "com.android.systemui" + flag { name: "floating_menu_overlaps_nav_bars_flag" namespace: "accessibility" description: "Adjusts bounds to allow the floating menu to render on top of navigation bars." bug: "283768342" -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 2d6e25776134..70832f594941 100644 --- a/packages/SystemUI/src/com/android/systemui/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1,8 +1,8 @@ -package: "com.android.systemui.aconfig" +package: "com.android.systemui" flag { name: "example_flag" namespace: "systemui" description: "An Example Flag" bug: "292511372" -} +}
\ No newline at end of file diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp index 8eb012d2e41c..6f53b42371c6 100644 --- a/packages/SystemUI/animation/Android.bp +++ b/packages/SystemUI/animation/Android.bp @@ -68,5 +68,6 @@ android_library { kotlincflags: ["-Xjvm-default=all"], // sdk_version must be specified, otherwise it compiles against private APIs. + min_sdk_version: "33", sdk_version: "current", } diff --git a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/BouncerSceneModule.kt index a7bd771400c0..1a5e22b2c5ee 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/src/com/android/apkverity/DummyActivity.java +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/BouncerSceneModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.android.apkverity; +package com.android.systemui.scene -import android.app.Activity; +import dagger.Module -/** Placeholder class just to generate some dex */ -public class DummyActivity extends Activity {} +@Module interface BouncerSceneModule diff --git a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/GoneSceneModule.kt index fe9126003967..5cc3b75df787 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/src/com/android/apkverity/feature_x/DummyActivity.java +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/GoneSceneModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,8 @@ * limitations under the License. */ -package com.android.apkverity.feature_x; +package com.android.systemui.scene -import android.app.Activity; +import dagger.Module -/** Placeholder class just to generate some dex */ -public class DummyActivity extends Activity {} +@Module interface GoneSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/LockscreenSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/LockscreenSceneModule.kt new file mode 100644 index 000000000000..725aef26cb86 --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/LockscreenSceneModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import dagger.Module + +@Module interface LockscreenSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt new file mode 100644 index 000000000000..387b05644f14 --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import dagger.Module + +@Module interface QuickSettingsSceneModule diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt new file mode 100644 index 000000000000..232c4211c7c1 --- /dev/null +++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ShadeSceneModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import dagger.Module + +@Module interface ShadeSceneModule diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerSceneModule.kt index 3e9b3975eef4..ddc3d3a31e94 100644 --- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/BouncerSceneModule.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 The Android Open Source Project + * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.scene.ui.composable +package com.android.systemui.scene import android.app.AlertDialog import android.content.Context @@ -22,39 +22,27 @@ import com.android.systemui.bouncer.ui.composable.BouncerScene import com.android.systemui.bouncer.ui.composable.BouncerSceneDialogFactory import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.keyguard.ui.composable.LockscreenScene -import com.android.systemui.qs.ui.composable.QuickSettingsScene import com.android.systemui.scene.shared.model.Scene -import com.android.systemui.shade.ui.composable.ShadeScene import com.android.systemui.statusbar.phone.SystemUIDialog +import dagger.Binds import dagger.Module import dagger.Provides +import dagger.multibindings.IntoSet @Module -object SceneModule { - @Provides - fun scenes( - bouncer: BouncerScene, - gone: GoneScene, - lockScreen: LockscreenScene, - qs: QuickSettingsScene, - shade: ShadeScene, - ): Set<Scene> { - return setOf( - bouncer, - gone, - lockScreen, - qs, - shade, - ) - } +interface BouncerSceneModule { + + @Binds @IntoSet fun bouncerScene(scene: BouncerScene): Scene + + companion object { - @Provides - @SysUISingleton - fun bouncerSceneDialogFactory(@Application context: Context): BouncerSceneDialogFactory { - return object : BouncerSceneDialogFactory { - override fun invoke(): AlertDialog { - return SystemUIDialog(context) + @Provides + @SysUISingleton + fun bouncerSceneDialogFactory(@Application context: Context): BouncerSceneDialogFactory { + return object : BouncerSceneDialogFactory { + override fun invoke(): AlertDialog { + return SystemUIDialog(context) + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/GoneSceneModule.kt index fcfdcebba2ea..bc3fef15e577 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/GoneSceneModule.kt @@ -14,27 +14,16 @@ * limitations under the License. */ -package com.android.systemui.scene.domain.startable +package com.android.systemui.scene -import com.android.systemui.CoreStartable -import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor +import com.android.systemui.scene.shared.model.Scene +import com.android.systemui.scene.ui.composable.GoneScene import dagger.Binds import dagger.Module -import dagger.multibindings.ClassKey -import dagger.multibindings.IntoMap +import dagger.multibindings.IntoSet @Module -interface SceneContainerStartableModule { +interface GoneSceneModule { - @Binds - @IntoMap - @ClassKey(SceneContainerStartable::class) - fun bind(impl: SceneContainerStartable): CoreStartable - - @Binds - @IntoMap - @ClassKey(WindowRootViewVisibilityInteractor::class) - fun bindWindowRootViewVisibilityInteractor( - impl: WindowRootViewVisibilityInteractor - ): CoreStartable + @Binds @IntoSet fun goneScene(scene: GoneScene): Scene } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/LockscreenSceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/LockscreenSceneModule.kt index c88737e6bd70..4d53cca66e5b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/LockscreenSceneModule.kt +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/LockscreenSceneModule.kt @@ -14,28 +14,36 @@ * limitations under the License. */ -@file:OptIn(ExperimentalCoroutinesApi::class) - -package com.android.systemui.keyguard.ui.view +package com.android.systemui.scene import android.view.View import com.android.systemui.dagger.SysUISingleton import com.android.systemui.keyguard.KeyguardViewConfigurator import com.android.systemui.keyguard.qualifiers.KeyguardRootView +import com.android.systemui.keyguard.ui.composable.LockscreenScene +import com.android.systemui.scene.shared.model.Scene +import dagger.Binds import dagger.Module import dagger.Provides +import dagger.multibindings.IntoSet import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi @Module -object LockscreenSceneModule { +interface LockscreenSceneModule { + + @Binds @IntoSet fun lockscreenScene(scene: LockscreenScene): Scene + + companion object { - @Provides - @SysUISingleton - @KeyguardRootView - fun viewProvider( - configurator: Provider<KeyguardViewConfigurator>, - ): () -> View { - return { configurator.get().getKeyguardRootView() } + @OptIn(ExperimentalCoroutinesApi::class) + @Provides + @SysUISingleton + @KeyguardRootView + fun viewProvider( + configurator: Provider<KeyguardViewConfigurator>, + ): () -> View { + return { configurator.get().getKeyguardRootView() } + } } } diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt new file mode 100644 index 000000000000..ee1f5259ec69 --- /dev/null +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/QuickSettingsSceneModule.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import com.android.systemui.qs.ui.composable.QuickSettingsScene +import com.android.systemui.scene.shared.model.Scene +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet + +@Module +interface QuickSettingsSceneModule { + + @Binds @IntoSet fun quickSettingsScene(scene: QuickSettingsScene): Scene +} diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ShadeSceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ShadeSceneModule.kt new file mode 100644 index 000000000000..c655d6ba3f2f --- /dev/null +++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ShadeSceneModule.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import com.android.systemui.scene.shared.model.Scene +import com.android.systemui.shade.ui.composable.ShadeScene +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet + +@Module +interface ShadeSceneModule { + + @Binds @IntoSet fun shadeScene(scene: ShadeScene): Scene +} diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt index b3b44cba832b..463253b9fb41 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt @@ -102,17 +102,19 @@ private fun LockscreenScene( longPressViewModel: KeyguardLongPressViewModel, modifier: Modifier = Modifier, ) { - var settingsMenu: View? = null + fun findSettingsMenu(): View { + return viewProvider().requireViewById(R.id.keyguard_settings_button) + } Box( modifier = modifier, ) { LongPressSurface( viewModel = longPressViewModel, - isSettingsMenuVisible = { settingsMenu?.isVisible == true }, + isSettingsMenuVisible = { findSettingsMenu().isVisible }, settingsMenuBounds = { val bounds = android.graphics.Rect() - settingsMenu?.getHitRect(bounds) + findSettingsMenu().getHitRect(bounds) bounds.toComposeRect() }, modifier = Modifier.fillMaxSize(), @@ -124,12 +126,8 @@ private fun LockscreenScene( // Remove the KeyguardRootView from any parent it might already have in legacy code // just in case (a view can't have two parents). (keyguardRootView.parent as? ViewGroup)?.removeView(keyguardRootView) - settingsMenu = keyguardRootView.requireViewById(R.id.keyguard_settings_button) keyguardRootView }, - update = { keyguardRootView -> - keyguardRootView.requireViewById<View>(R.id.lock_icon_view) - }, modifier = Modifier.fillMaxSize(), ) } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt index 31cbcb90769a..019287d8d500 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt @@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.motionEventSpy import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.motionEventSpy import androidx.compose.ui.input.pointer.pointerInput diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml index 027166ff72c0..c7c863b70336 100644 --- a/packages/SystemUI/res-keyguard/values-da/strings.xml +++ b/packages/SystemUI/res-keyguard/values-da/strings.xml @@ -118,7 +118,7 @@ <string name="kg_prompt_reason_device_admin" msgid="6961159596224055685">"Enheden er blevet låst af administratoren"</string> <string name="kg_prompt_reason_user_request" msgid="6015774877733717904">"Enheden blev låst manuelt"</string> <string name="kg_face_not_recognized" msgid="7903950626744419160">"Ikke genkendt"</string> - <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aktivér kameraadgang i Indstillinger for at bruge ansigtslås"</string> + <string name="kg_face_sensor_privacy_enabled" msgid="939511161763558512">"Aktivér kameraadgang i Indstillinger for at bruge ansigtsoplåsning"</string> <string name="kg_password_default_pin_message" msgid="1434544655827987873">"{count,plural, =1{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage, før du skal kontakte dit mobilselskab for at låse din enhed op.}one{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage.}other{Angiv pinkoden til SIM-kortet. Du har # forsøg tilbage.}}"</string> <string name="kg_password_default_puk_message" msgid="1025139786449741950">"{count,plural, =1{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}one{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}other{SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har # forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.}}"</string> <string name="clock_title_default" msgid="6342735240617459864">"Standard"</string> diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml deleted file mode 100644 index 3baae3376bd0..000000000000 --- a/packages/SystemUI/res/layout/zen_mode_condition.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2014 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. ---> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:theme="@style/Theme.SystemUI.QuickSettings" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:clipChildren="false" - android:layout_marginStart="1dp" - android:layout_marginEnd="0dp" - android:layout_weight="1" - android:gravity="center_vertical" > - - <LinearLayout - android:id="@android:id/content" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:minHeight="48dp" - android:gravity="center_vertical" - android:layout_centerVertical="true" - android:orientation="vertical" - android:layout_toEndOf="@android:id/checkbox" - android:layout_toStartOf="@android:id/button1"> - - <TextView - android:id="@android:id/text1" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:ellipsize="end" - android:textAlignment="viewStart" - android:maxLines="1" - android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" /> - - <TextView - android:id="@android:id/text2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/zen_mode_condition_detail_item_interline_spacing" - android:ellipsize="end" - android:textAlignment="viewStart" - android:maxLines="1" - android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary" /> - - </LinearLayout> - - <ImageView - android:id="@android:id/button1" - style="@style/QSBorderlessButton" - android:background="@drawable/ripple_drawable_20dp" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_centerVertical="true" - android:scaleType="center" - android:layout_toStartOf="@android:id/button2" - android:contentDescription="@string/accessibility_quick_settings_less_time" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_qs_minus" /> - - <ImageView - android:id="@android:id/button2" - style="@style/QSBorderlessButton" - android:background="@drawable/ripple_drawable_20dp" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_alignParentEnd="true" - android:scaleType="center" - android:layout_centerVertical="true" - android:contentDescription="@string/accessibility_quick_settings_more_time" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_qs_plus" /> - -</RelativeLayout> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index a1db50d10197..206a7eeda5c1 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"\'n Ander toestel het versoek om die stelseltaal te verander"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Verander taal"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Hou huidige taal"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Deel wi-fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Laat draadlose ontfouting op hierdie netwerk toe?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Netwerknaam (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-adres (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Laat altyd toe op hierdie netwerk"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Verkeerde patroon"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Verkeerde wagwoord"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Te veel verkeerde pogings.\nProbeer oor <xliff:g id="NUMBER">%d</xliff:g> sekondes weer."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Noodgeval"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Probeer weer. Poging <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> van <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Jou data sal uitgevee word"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"As jy met jou volgende poging \'n verkeerde patroon invoer, sal hierdie toestel se data uitgevee word."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Wanneer jy deel, opneem of uitsaai, het <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot enigiets wat op jou skerm sigbaar is of op jou toestel gespeel word. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Wanneer jy ’n app deel, opneem of uitsaai, het <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot enigiets wat in daardie app gewys of gespeel word. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Begin"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> het hierdie opsie gedeaktiveer"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Begin uitsaai?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Wanneer jy uitsaai, het Android toegang tot enigiets wat op jou skerm sigbaar is of op jou toestel gespeel word. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Wanneer jy ’n app uitsaai, het Android toegang tot enigiets wat in daardie app gewys of gespeel word. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandag is aan"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stel versteknotasapp in Instellings"</string> <string name="install_app" msgid="5066668100199613936">"Installeer app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoon en kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Onlangse appgebruik"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sien onlangse toegang"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index bc7273d1e08d..09157f8a7b6d 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"በሌላ መሣሪያ የተጠየቀ የስርዓት ቋንቋ ለውጥ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ቋንቋ ቀይር"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"አሁን ያለውን ቋንቋ አቆይ"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fiን አጋራ"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"በዚህ አውታረ መረብ ላይ ገመድ-አልባ debugging ይፈቀድ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"የአውታረ መረብ ስም (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nየWi‑Fi አድራሻ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ሁልጊዜ በዚህ አውታረ መረብ ላይ ፍቀድ"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"የተሳሳተ ሥርዓተ ጥለት"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"የተሳሳተ የይለፍ ቃል"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ከልክ በላይ ብዙ የተሳሳቱ ሙከራዎች።\nበ<xliff:g id="NUMBER">%d</xliff:g> ሰከንዶች ውስጥ እንደገና ይሞክሩ።"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ድንገተኛ አደጋ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"እንደገና ይሞክሩ። ሙከራ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ከ<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>።"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"የእርስዎ ውሂብ ይሰረዛል"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"በሚቀጥለው ሙከራ ላይ ትክክል ያልሆነ ሥርዓተ ጥለት ካስገቡ የዚህ መሣሪያ ውሂብ ይሰረዛል።"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"እርስዎ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በማያ ገጽዎ ላይ ለሚታይ ወይም በመሣሪያዎ ላይ ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"አንድን መተግበሪያ ሲያጋሩ፣ ሲቀርጹ ወይም cast ሲያደርጉ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ጀምር"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ይህን አማራጭ አሰናክሏል"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"cast ማድረግ ይጀምር?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"እርስዎ cast በሚያደርጉበት ጊዜ Android በማያ ገጽዎ ላይ ለሚታይ ወይም በመሣሪያዎ ላይ ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"አንድን መተግበሪያ cast ሲያደርጉ Android በዚያ መተግበሪያ ላይ ለሚታይ ወይም ለሚጫወት ማንኛውም ነገር መዳረሻ አለው። ስለዚህ እንደ ይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"የረዳት ትኩረት በርቷል"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"በቅንብሮች ውስጥ ነባሪ የማስታወሻዎች መተግበሪያን ያቀናብሩ"</string> <string name="install_app" msgid="5066668100199613936">"መተግበሪያን ጫን"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ማይክሮፎን እና ካሜራ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"የቅርብ ጊዜ የመተግበሪያ አጠቃቀም"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"የቅርብ ጊዜ መዳረሻን አሳይ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 7b8f23a5e222..31b7cbe31cc2 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"طلب جهاز آخر تغيير لغة النظام."</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"تغيير اللغة"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"الإبقاء على اللغة الحالية"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"مشاركة اتصال Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"هل تريد السماح باستخدام ميزة \"تصحيح الأخطاء اللاسلكي\" على هذه الشبكة؟"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"اسم الشبكة (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nعنوان شبكة Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"السماح باستخدام هذه الميزة على هذه الشبكة دائمًا"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"النقش غير صحيح."</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"كلمة مرور غير صحيحة"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"تم إجراء عدد كبير جدًا من المحاولات غير الصحيحة.\nأعد المحاولة خلال <xliff:g id="NUMBER">%d</xliff:g> ثانية."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"الطوارئ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"يُرجى إعادة المحاولة. المحاولة <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> من <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"سيتم حذف بياناتك"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"عند إدخال نقش غير صحيح في المحاولة التالية، سيتم حذف بيانات هذا الجهاز."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"أثناء المشاركة أو التسجيل أو البثّ، يمكن لتطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" الوصول إلى كل المحتوى المعروض على شاشتك أو الذي يتم تشغيله على جهاز، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"أثناء مشاركة محتوى تطبيق أو تسجيله أو بثّه، يمكن لتطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله في ذلك التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"بدء"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"تم إيقاف هذا الخيار من خلال تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>."</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"هل تريد بدء البثّ؟"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"أثناء البثّ، يمكن لنظام Android الوصول إلى كل المحتوى المعروض على شاشتك أو الذي يتم تشغيله على جهازك، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"أثناء بثّ محتوى تطبيق، يمكن لنظام Android الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله في ذلك التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"ميزة لفت انتباه \"مساعد Google\" مفعّلة."</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"يمكنك ضبط تطبيق تدوين الملاحظات التلقائي في \"الإعدادات\"."</string> <string name="install_app" msgid="5066668100199613936">"تثبيت التطبيق"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"الميكروفون والكاميرا"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"آخر استخدام في التطبيقات"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"عرض آخر استخدام في التطبيقات"</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index 9b3be3c2ee1c..732d19d09283 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"অন্য এটা ডিভাইচে ছিষ্টেমৰ ভাষা সলনি কৰাৰ অনুৰোধ কৰিছে"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ভাষা সলনি কৰক"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"বৰ্তমানৰ ভাষাটো ৰাখক"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ৱাই-ফাই শ্বেয়াৰ কৰক"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"এই নেটৱৰ্কত ৱায়াৰলেচ ডি\'বাগিংৰ অনুমতি দিবনে?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"নেটৱৰ্কৰ নাম (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nৱাই-ফাইৰ ঠিকনা (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"এই নেটৱৰ্কত সদায় অনুমতি দিয়ক"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ভুল আৰ্হি"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ভুল পাছৱৰ্ড"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"বহুসংখ্যক ভুল প্ৰয়াস।\n<xliff:g id="NUMBER">%d</xliff:g>ছেকেণ্ডত পুনৰ চেষ্টা কৰক।"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"জৰুৰীকালীন"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"আকৌ চেষ্টা কৰক। <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> টাৰ প্ৰয়াসৰ ভিতৰত <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> টা প্ৰয়াস।"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"আপোনাৰ ডেটা মচি পেলোৱা হ’ব"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"আপুনি পৰৱৰ্তী প্ৰয়াসত এটা ভুল আৰ্হি দিলে, এই ডিভাইচটোৰ ডেটা মচি পেলোৱা হ’ব।"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"আপুনি শ্বেয়াৰ কৰা, ৰেকৰ্ড কৰা অথবা কাষ্ট কৰাৰ সময়ত, আপোনাৰ স্ক্ৰীনখনত দৃশ্যমান হোৱা যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"আপুনি শ্বেয়াৰ কৰা, ৰেকৰ্ড কৰা অথবা কাষ্ট কৰাৰ সময়ত, সেইটো এপত দৃশ্যমান যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"আৰম্ভ কৰক"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ এই বিকল্পটো অক্ষম কৰিছে"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"কাষ্ট কৰিবলৈ আৰম্ভ কৰিবনে?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"আপুনি কাষ্ট কৰাৰ সময়ত, আপোনাৰ স্ক্ৰীনখনত দৃশ্যমান যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ Androidৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"আপুনি এটা এপ্ কাষ্ট কৰাৰ সময়ত সেইটো এপত দৃশ্যমান হোৱা যিকোনো বস্তু অথবা আপোনাৰ ডিভাইচত প্লে’ কৰা যিকোনো সমললৈ Androidৰ এক্সেছ থাকে। গতিকে, পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistantএ আপোনাৰ কথা শুনি আছে"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ছেটিঙত টোকাৰ ডিফ’ল্ট এপ্ ছেট কৰক"</string> <string name="install_app" msgid="5066668100199613936">"এপ্টো ইনষ্টল কৰক"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্ৰ’ফ’ন আৰু কেমেৰা"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"শেহতীয়া এপৰ ব্যৱহাৰ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"শেহতীয়া এক্সেছ চাওক"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index af63640676eb..080f450432fc 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Sistem dilinin dəyişdirilməsi başqa cihaz tərəfindən tələb olunur"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Dili dəyişin"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Cari dili saxlayın"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi-ı paylaşın"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Bu şəbəkədə WiFi sazlamasına icazə verilsin?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Şəbəkə Adı (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Ünvanı (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Bu şəbəkədə həmişə icazə verilsin"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Yanlış model"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Yanlış parol"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Həddindən çox yanlış cəhd.\n<xliff:g id="NUMBER">%d</xliff:g> saniyəyə yenidən cəhd edin."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Fövqəladə hal"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Yenidən cəhd edin. Cəhd: <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Data silinəcək"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Növbəti cəhddə yanlış model daxil etsəniz, bu cihazın datası silinəcək."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Paylaşım, qeydəalma və ya yayım zamanı <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ekranda görünən, yaxud cihazda oxudulan məlumatlara giriş edə bilir. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Tətbiq paylaşdıqda, qeydə aldıqda və ya yayımladıqda <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> həmin tətbiqdə göstərilən, yaxud oxudulan məlumatlara giriş edə bilir. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Başlayın"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçimi deaktiv edib"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Yayım başladılsın?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Yayım zamanı Android-in ekranda görünən, yaxud cihazda oxudulan məlumatlara girişi olur. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Tətbiq yayımladıqda Android-in həmin tətbiqdə göstərilən və ya oxudulan məlumatlara girişi olur. Parol, ödəniş detalları, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent aktivdir"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlarda defolt qeydlər tətbiqi ayarlayın"</string> <string name="install_app" msgid="5066668100199613936">"Tətbiqi quraşdırın"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon və kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Son tətbiq istifadəsi"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son girişə baxı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 94c526515715..b524c343548f 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj je zatražio promenu jezika sistema"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promeni jezik"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži aktuelni jezik"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Deli WiFi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Želite da dozvolite bežično otklanjanje grešaka na ovoj mreži?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi adresa (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvek dozvoli na ovoj mreži"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pogrešan šablon"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pogrešna lozinka"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Previše netačnih pokušaja.\n Probajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> sek."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Hitan slučaj"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Probajte ponovo. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. pokušaj od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Podaci će se izbrisati"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ako unesete netačan šablon pri sledećem pokušaju, izbrisaćemo podatke sa ovog uređaja."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kada delite, snimate ili prebacujete, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i video snimcima."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i video snimcima."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pokreni"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila ovu opciju"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite da započnete prebacivanje?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kada prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i video snimcima."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kada prebacujete aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i video snimcima."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pomoćnik je u aktivnom stanju"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Podesite podrazumevanu aplikaciju za beleške u Podešavanjima"</string> <string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno koristila aplikacija"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index e271408f43b7..dd8199edb123 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Іншая прылада запытала змяненне мовы сістэмы"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Змяніць мову"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Захаваць бягучую мову"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Абагуліць Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Дазволіць адладку па Wi-Fi у гэтай сетцы?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Назва сеткі (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nАдрас Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Заўсёды дазваляць у гэтай сетцы"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Няправільны ўзор разблакіроўкі"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Няправільны пароль"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Занадта шмат няўдалых спроб.\nПаспрабуйце зноў праз <xliff:g id="NUMBER">%d</xliff:g> с."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Экстранны выклік"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Паўтарыце спробу. Спроба <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> з <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Вашы даныя будуць выдалены"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Калі вы ўведзяце няправільны ўзор разблакіроўкі яшчэ раз, даныя з гэтай прылады будуць выдалены."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Калі пачынаецца абагульванне, запіс ці трансляцыя, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> атрымлівае доступ да ўсяго змесціва, якое паказваецца на экране ці прайграецца на прыладзе. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Калі пачынаецца абагульванне, запіс ці трансляцыя змесціва праграмы, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> атрымлівае доступ да ўсяго змесціва, якое паказваецца ці прайграецца ў праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Пачаць"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" адключыла гэты параметр"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Пачаць трансляцыю?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Калі адбываецца трансляцыя, Android мае доступ да ўсяго змесціва, якое паказваецца на экране ці прайграецца на прыладзе. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Калі адбываецца трансляцыя змесціва праграмы, Android мае доступ да ўсяго змесціва, якое паказваецца ці прайграецца ў праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Памочнік гатовы выконваць каманды"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайце ў Наладах стандартную праграму для нататак"</string> <string name="install_app" msgid="5066668100199613936">"Усталяваць праграму"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрафон і камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Нядаўна выкарыстоўваліся праграмамі"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Паглядзець нядаўні доступ"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 38781a4fe64c..896756dc9b37 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Друго устройство е заявило промяна на езика на системата"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промяна на езика"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Текущ език: Запазване"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Споделяне на Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Разрешаване на безжичното отстраняване на грешки?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Име на мрежата (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nАдрес на Wi‑Fi мрежата (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Винаги да се разрешава в тази мрежа"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Грешна фигура"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Грешна парола"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Твърде много неправилни опити.\nОпитайте отново след <xliff:g id="NUMBER">%d</xliff:g> секунди."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Спешен случай"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Опитайте отново. Опит <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> от <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Данните ви ще бъдат изтрити"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ако въведете неправилна фигура при следващия опит, данните от това устройство ще бъдат изтрити."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Когато споделяте, записвате или предавате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се вижда на екрана ви или се възпроизвежда на устройството ви. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Когато споделяте, записвате или предавате дадено приложение, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има достъп до всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Стартиране"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> деактивира тази опция"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Искате ли да стартирате предаване?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Когато предавате, Android има достъп до всичко, което се вижда на екрана ви или се възпроизвежда на устройството ви. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Когато предавате дадено приложение, Android има достъп до всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Функцията за активиране на Асистент е включена"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартно приложение за бележки от настройките"</string> <string name="install_app" msgid="5066668100199613936">"Инсталиране на приложението"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Скорошно използване на приложението"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Вижте скорошния достъп"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index b6b539cea93e..5c1b445fc1d9 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"অন্য ডিভাইসের দ্বারা সিস্টেমের ভাষা পরিবর্তনের অনুরোধ করা হয়েছে"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ভাষা পরিবর্তন করুন"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"বর্তমান ভাষা রাখুন"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ওয়াই-ফাই শেয়ার করুন"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"এই নেটওয়ার্কে ওয়্যারলেস ডিবাগিংয়ের অনুমতি দেবেন?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"নেটওয়ার্কের নাম (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nওয়াই-ফাই অ্যাড্রেস (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"এই নেটওয়ার্কে সবসময় অনুমতি দিন"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ভুল প্যাটার্ন"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ভুল পাসওয়ার্ড"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"অনেকবার ভুল চেষ্টা করা হয়েছে। \n<xliff:g id="NUMBER">%d</xliff:g> সেকেন্ডের মধ্যে আবার চেষ্টা করুন।"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"জরুরি"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"আবার চেষ্টা করুন। <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> বারের মধ্যে <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> বার চেষ্টা করা হয়েছে।"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"আপনার ডেটা মুছে দেওয়া হবে"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"আপনি পরের বারও ভুল প্যাটার্ন আঁকলে এই ডিভাইসের ডেটা মুছে দেওয়া হবে।"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"আপনি শেয়ার, রেকর্ড বা কাস্ট করার সময়, স্ক্রিনে দৃশ্যমান বা ডিভাইসে চালানো সব কিছুই <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"আপনি কোনও অ্যাপ শেয়ার, রেকর্ড বা কাস্ট করার সময়, সেই অ্যাপে দেখা যায় বা চালানো হয় এমন সব কিছু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"শুরু করুন"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই বিকল্পটি বন্ধ করে দিয়েছে"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"কাস্ট করা শুরু করবেন?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"আপনি কাস্ট করার সময়, স্ক্রিনে দৃশ্যমান বা ডিভাইসে চালানো সবকিছুই Android অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"আপনি কোনও অ্যাপ কাস্ট করার সময়, ওই অ্যাপে দেখানো বা চালানো হয় এমন সবকিছুই Android অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"অ্যাসিস্ট্যান্ট আপনার কথা শোনার জন্য চালু করা আছে"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"\'সেটিংস\' থেকে ডিফল্ট নোট নেওয়ার অ্যাপ সেট করুন"</string> <string name="install_app" msgid="5066668100199613936">"অ্যাপ ইনস্টল করুন"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"মাইক্রোফোন ও ক্যামেরা"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"সম্প্রতি ব্যবহার করা অ্যাপ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"সাম্প্রতিক অ্যাক্সেস দেখুন"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index b5fa00eec995..63f62f173ec5 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Promjenu jezika sistema je zatražio drugi uređaj"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promijeni jezik"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži trenutni jezik"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Dijeli WiFi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Dozvoliti bežično otklanjanje grešaka na ovoj mreži?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa WiFi mreže (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dozvoli na ovoj mreži"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pogrešan uzorak"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pogrešna lozinka"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Previše pogrešnih pokušaja.\n Pokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Hitan slučaj"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Pokušajte ponovo. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. pokušaj od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vaši podaci će se izbrisati"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ako u sljedećem pokušaju unesete neispravan uzorak, podaci ovog uređaja će se izbrisati."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kada dijelite, snimate ili emitirate, aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kada dijelite, snimate ili emitirate aplikaciju, aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pokreni"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila tu opciju"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Pokrenuti emitiranje?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kada emitirate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kada emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pažnja Asistenta je uključena"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u Postavkama"</string> <string name="install_app" msgid="5066668100199613936">"Instaliraj aplikaciju"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavno korištenje aplikacije"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Prikaži nedavni pristup"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index fea2ee67e3a9..f54a0acca100 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Un altre dispositiu ha sol·licitat canviar l\'idioma del sistema"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Canvia l\'idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mantén l\'idioma actual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Comparteix la Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vols permetre la depuració sense fil en aquesta xarxa?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nom de la xarxa (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdreça Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permet sempre en aquesta xarxa"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Patró incorrecte"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Contrasenya incorrecta"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Has superat el nombre d\'intents incorrectes permesos.\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER">%d</xliff:g> segons."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergència"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Torna-ho a provar. Intent <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Se suprimiran les teves dades"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Si tornes a introduir un patró incorrecte, se suprimiran les dades del dispositiu."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quan comparteixes, graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quan comparteixes, graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Inicia"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha desactivat aquesta opció"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vols iniciar una emissió?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Quan emets contingut, Android té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Quan emets una aplicació, Android té accés a qualsevol cosa que es mostri o que es reprodueixi en aquella aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"L\'Assistent està activat"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defineix l\'aplicació de notes predeterminada a Configuració"</string> <string name="install_app" msgid="5066668100199613936">"Instal·la l\'aplicació"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micròfon i càmera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Ús recent de l\'aplicació"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Mostra l\'accés recent"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 339ba71a0b82..1bfe1f4ecdad 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Jiné zařízení požádalo o změnu systémového jazyka"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Změnit jazyk"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zachovat stávající jazyk"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Sdílení sítě Wi-Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Povolit v této síti bezdrátové ladění?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Název sítě (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"V této síti vždy povolit"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Nesprávné gesto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Nesprávné heslo"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Příliš mnoho neplatných pokusů.\nZkuste to znovu za <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Stav nouze"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Zkuste to znovu. Pokus <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> z <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vaše data budou smazána"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Pokud při příštím pokusu zadáte nesprávné gesto, data v tomto zařízení budou smazána."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Během sdílení, nahrávání nebo odesílání má <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Během sdílení, nahrávání nebo odesílání aplikace má <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Začít"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> tuto možnost zakázala"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Začít odesílat?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Během odesílání má Android přístup ke všemu, co je viditelné na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Během odesílání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pozornost Asistenta je zapnutá"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Výchozí aplikaci pro poznámky nastavíte v Nastavení"</string> <string name="install_app" msgid="5066668100199613936">"Nainstalovat aplikaci"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon a fotoaparát"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávné použití aplikacemi"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobrazit nedávný přístup"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 79ba451c4aae..17853e7228d3 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"En anden enhed har anmodet om en ændring af systemsproget"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Skift sprog"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Behold nuværende sprog"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Del Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vil du tillade trådløs fejlretning på dette netværk?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Netværksnavn (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-adresse (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Tillad altid på dette netværk"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Forkert mønster"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Forkert adgangskode"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"For mange mislykkede forsøg. \nPrøv igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Nødsituation"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Prøv igen. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. forsøg ud af <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Dine data bliver slettet"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Hvis du angiver et forkert mønster i næste forsøg, slettes dataene på denne enhed."</string> @@ -182,11 +180,11 @@ <string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string> <string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"Hvis du vil konfigurere oplåsning med fingeraftryk igen, bliver dine nuværende fingeraftryksbilleder og -modeller slettet.\n\nNår de er slettet, skal du konfigurere oplåsning med fingeraftryk igen for at bruge dit fingeraftryk til at låse din telefon op eller verificere din identitet."</string> <string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Oplåsning med fingeraftryk kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string> - <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Konfigurer ansigtslås igen"</string> - <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Ansigtslås"</string> - <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Konfigurer ansigtslås"</string> - <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Hvis du vil konfigurere ansigtslås igen, bliver din nuværende ansigtsmodel slettet.\n\nDu skal konfigurere funktionen igen for at bruge ansigtsgenkendelse til at låse din telefon op."</string> - <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Ansigtslås kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string> + <string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Konfigurer ansigtsoplåsning igen"</string> + <string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Ansigtsoplåsning"</string> + <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Konfigurer ansigtsoplåsning"</string> + <string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Hvis du vil konfigurere ansigtsoplåsning igen, bliver din nuværende ansigtsmodel slettet.\n\nDu skal konfigurere funktionen igen for at bruge ansigtsgenkendelse til at låse din telefon op."</string> + <string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Ansigtsoplåsning kunne ikke konfigureres. Gå til Indstillinger for at prøve igen."</string> <string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Sæt fingeren på fingeraftrykssensoren"</string> <string name="fingerprint_dialog_authenticated_confirmation" msgid="1603899612957562862">"Tryk på oplåsningsikonet for at fortsætte"</string> <string name="fingerprint_dialog_use_fingerprint_instead" msgid="6178228876763024452">"Ansigtet kan ikke genkendes. Brug fingeraftryk i stedet."</string> @@ -194,7 +192,7 @@ <skip /> <string name="keyguard_face_failed" msgid="9044619102286917151">"Ansigt kan ikke genkendes"</string> <string name="keyguard_suggest_fingerprint" msgid="8742015961962702960">"Brug fingeraftryk i stedet"</string> - <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Ansigtslås er utilgængelig"</string> + <string name="keyguard_face_unlock_unavailable" msgid="1581949044193418736">"Ansigtsoplåsning er utilgængelig"</string> <string name="accessibility_bluetooth_connected" msgid="4745196874551115205">"Bluetooth tilsluttet."</string> <string name="accessibility_battery_unknown" msgid="1807789554617976440">"Batteriniveauet er ukendt."</string> <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"Tilsluttet <xliff:g id="BLUETOOTH">%s</xliff:g>."</string> @@ -369,7 +367,7 @@ <string name="keyguard_face_successful_unlock" msgid="4203999851465708287">"Låst op via ansigtsgenkendelse"</string> <string name="keyguard_face_successful_unlock_alt1" msgid="5853906076353839628">"Ansigtet er genkendt"</string> <string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string> - <string name="accesssibility_keyguard_retry" msgid="8880238862712870676">"Stryg opad for at prøve ansigtslåsen igen"</string> + <string name="accesssibility_keyguard_retry" msgid="8880238862712870676">"Stryg opad for at prøve ansigtsoplåsning igen"</string> <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string> <string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string> <string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Når du deler, optager eller caster, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> adgang til alt, der er synligt på din skærm eller afspilles på din enhed. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Når du deler, optager eller caster en app, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> adgang til alt, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktiveret denne valgmulighed"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vil du begynde at caste?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Når du caster, har Android adgang til alt, der vises på din skærm eller afspilles på din enhed. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Når du caster en app, har Android adgang til alt, der vises eller afspilles i den pågældende app. Vær derfor forsigtig med ting såsom adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent lytter"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Angiv standardapp til noter i Indstillinger"</string> <string name="install_app" msgid="5066668100199613936">"Installer app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Seneste brug af apps"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se seneste adgang"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 4f08805ebdfe..822ab277ba85 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Von einem anderen Gerät wurde eine Änderung der Systemsprache angefordert"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Sprache ändern"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Aktuelle Sprache nutzen"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"WLAN teilen"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Debugging über WLAN in diesem Netzwerk zulassen?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Netzwerkname (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWLAN-Adresse (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Immer in diesem Netzwerk zulassen"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Falsches Muster"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Falsches Passwort"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Zu viele Fehlversuche.\nBitte probiere es in <xliff:g id="NUMBER">%d</xliff:g> Sekunden noch einmal."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Notfall"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Bitte probier es noch einmal. Versuch <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> von <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Deine Daten werden gelöscht"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Wenn du beim nächsten Versuch ein falsches Muster eingibst, werden die Daten auf diesem Gerät gelöscht."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Beim Teilen, Aufnehmen oder Streamen hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Beim Teilen, Aufnehmen oder Streamen einer App hat <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder von ihr wiedergegeben werden. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Starten"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> hat diese Option deaktiviert"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Stream starten?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Beim Streamen hat Android Zugriff auf alle Inhalte, die auf deinem Bildschirm sichtbar sind oder von deinem Gerät wiedergegeben werden. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Beim Streamen einer App hat Android Zugriff auf alle Inhalte, die in dieser App sichtbar sind oder von ihr wiedergegeben werden. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant-Aktivierung an"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standard-Notizen-App in den Einstellungen einrichten"</string> <string name="install_app" msgid="5066668100199613936">"App installieren"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon & Kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Kürzliche App-Nutzung"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kürzliche Zugriffe ansehen"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 63337fd90c15..c33b7534198c 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ζητήθηκε αλλαγή της γλώσσας συστήματος από άλλη συσκευή"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Αλλαγή γλώσσας"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Διατήρ. τρέχουσας γλώσσας"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Κοινοποίηση Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Να επιτρέπεται ασύρματος εντοπ. σφαλ. στο δίκτυο;"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Όνομα δικτύου (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nΔιεύθυνση Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Να επιτρέπεται πάντα σε αυτό το δίκτυο"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Εσφαλμένο μοτίβο"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Εσφαλμένος κωδικός πρόσβασης"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Πάρα πολλές αποτυχημένες προσπάθειες.\nΔοκιμάστε ξανά σε <xliff:g id="NUMBER">%d</xliff:g> δευτερόλεπτα."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Έκτακτη ανάγκη"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Προσπαθήστε ξανά. Προσπάθεια <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> από <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Τα δεδομένα σας θα διαγραφούν"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Εάν εισαγάγετε εσφαλμένο μοτίβο στην επόμενη προσπάθεια, τα δεδομένα αυτής της συσκευής θα διαγραφούν."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Όταν κάνετε κοινή χρήση, εγγραφή ή μετάδοση, η εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> έχει πρόσβαση σε οτιδήποτε είναι ορατό στην οθόνη σας ή αναπαράγεται στη συσκευή σας. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Όταν κάνετε κοινή χρήση, εγγραφή ή μετάδοση μιας εφαρμογής, η εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Έναρξη"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> απενεργοποίησε αυτήν την επιλογή"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Έναρξη μετάδοσης;"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Όταν κάνετε μετάδοση, το Android έχει πρόσβαση σε οτιδήποτε είναι ορατό στην οθόνη σας ή αναπαράγεται στη συσκευή σας. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Όταν κάνετε μετάδοση μιας εφαρμογής, το Android έχει πρόσβαση σε οτιδήποτε είναι ορατό ή αναπαράγεται στη συγκεκριμένη εφαρμογή. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ο Βοηθός βρίσκεται σε αναμονή"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ορίστε την προεπιλεγμένη εφαρμογή σημειώσεων στις Ρυθμίσεις"</string> <string name="install_app" msgid="5066668100199613936">"Εγκατάσταση εφαρμογής"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Μικρόφωνο και Κάμερα"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Πρόσφατη χρήση εφαρμογής"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Εμφάνιση πρόσφατης πρόσβασης"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 7fbd4bf66aba..901459dea907 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Keep current language"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Share Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Allow wireless debugging on this network?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Network Name (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Address (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Wrong pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Wrong password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Too many incorrect attempts.\nTry again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Try again. Attempt <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> of <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Your data will be deleted"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"If you enter an incorrect pattern on the next attempt, this device’s data will be deleted."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"When you’re sharing, recording or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"When you’re sharing, recording or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant attention on"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string> <string name="install_app" msgid="5066668100199613936">"Install app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string> + <string name="enable_display" msgid="8308309634883321977">"Enable display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string> diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml index 0e50776c3308..01aa63784bbd 100644 --- a/packages/SystemUI/res/values-en-rCA/strings.xml +++ b/packages/SystemUI/res/values-en-rCA/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Keep current language"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Share Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Allow wireless debugging on this network?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Network Name (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Address (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Wrong pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Wrong password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Too many incorrect attempts.\nTry again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Try again. Attempt <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> of <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Your data will be deleted"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"If you enter an incorrect pattern on the next attempt, this device’s data will be deleted."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"When you’re sharing, recording, or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"When you’re sharing, recording, or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant attention on"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string> <string name="install_app" msgid="5066668100199613936">"Install app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string> + <string name="enable_display" msgid="8308309634883321977">"Enable display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone & Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 7fbd4bf66aba..901459dea907 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Keep current language"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Share Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Allow wireless debugging on this network?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Network Name (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Address (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Wrong pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Wrong password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Too many incorrect attempts.\nTry again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Try again. Attempt <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> of <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Your data will be deleted"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"If you enter an incorrect pattern on the next attempt, this device’s data will be deleted."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"When you’re sharing, recording or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"When you’re sharing, recording or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant attention on"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string> <string name="install_app" msgid="5066668100199613936">"Install app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string> + <string name="enable_display" msgid="8308309634883321977">"Enable display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 7fbd4bf66aba..901459dea907 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Keep current language"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Share Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Allow wireless debugging on this network?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Network Name (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Address (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Wrong pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Wrong password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Too many incorrect attempts.\nTry again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Try again. Attempt <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> of <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Your data will be deleted"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"If you enter an incorrect pattern on the next attempt, this device’s data will be deleted."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"When you’re sharing, recording or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"When you’re sharing, recording or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant attention on"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string> <string name="install_app" msgid="5066668100199613936">"Install app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string> + <string name="enable_display" msgid="8308309634883321977">"Enable display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone and Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string> diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml index 876bb0e9678e..c496aeea9325 100644 --- a/packages/SystemUI/res/values-en-rXC/strings.xml +++ b/packages/SystemUI/res/values-en-rXC/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"System language change requested by another device"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Change language"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Keep current language"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Share Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Allow wireless debugging on this network?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Network Name (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Address (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Always allow on this network"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Wrong pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Wrong password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Too many incorrect attempts.\nTry again in <xliff:g id="NUMBER">%d</xliff:g> seconds."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Try again. Attempt <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> of <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Your data will be deleted"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"If you enter an incorrect pattern on the next attempt, this device’s data will be deleted."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"When you’re sharing, recording, or casting, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"When you’re sharing, recording, or casting an app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Start"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant attention on"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Set default notes app in Settings"</string> <string name="install_app" msgid="5066668100199613936">"Install app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Mirror to external display?"</string> + <string name="enable_display" msgid="8308309634883321977">"Enable display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone & Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app use"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"See recent access"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index e5d197d18017..3653839f5a00 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Cambio de idioma del sistema solicitado por otro dispositivo"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mantener el idioma actual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Compartir Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"¿Quieres permitir la depuración inalámbrica en esta red?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nombre de red (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nDirección Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir siempre en esta red"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Patrón incorrecto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Contraseña incorrecta"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Demasiados intentos incorrectos.\nVuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergencia"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Vuelve a intentarlo. Intento <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Se borrarán tus datos"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Si ingresas un patrón incorrecto en el próximo intento, se borrarán los datos de este dispositivo."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Cuando compartas, grabes o transmitas contenido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo lo que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Cuando compartas, grabes o transmitas una app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo el contenido que se muestre o que reproduzcas en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Iniciar"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> inhabilitó esta opción"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"¿Quieres comenzar a transmitir contenido?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Cuando transmitas contenido, Android podrá acceder a todo lo que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Cuando transmitas una app, Android podrá acceder a todo el contenido que se muestre o que reproduzcas en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistente está prestando atención"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la app de notas predeterminada en Configuración"</string> <string name="install_app" msgid="5066668100199613936">"Instalar app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en apps"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver accesos recientes"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index c2a6b7122d0f..0680821c1729 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Otro dispositivo ha solicitado un cambio en el idioma del sistema"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Seguir en este idioma"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Compartir Wi-Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"¿Permitir la depuración inalámbrica en esta red?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nombre de la red (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nDirección Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir siempre en esta red"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Patrón incorrecto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Contraseña incorrecta"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Demasiados intentos fallidos.\n Vuelve a intentarlo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergencia"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Vuelve a intentarlo. Intento <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Tus datos se eliminarán"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Si vuelves a introducir un patrón incorrecto, los datos de este dispositivo se eliminarán."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Cuando compartes, grabas o envías contenido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede acceder a todo lo que se muestre en la pantalla o se reproduzca en tu dispositivo. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Cuando compartes, grabas o envías una aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede acceder a todo lo que se muestre o se reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Empezar"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha inhabilitado esta opción"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"¿Empezar a enviar contenido?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Cuando envías contenido, Android puede acceder a todo lo que se muestre en la pantalla o se reproduzca en tu dispositivo. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Cuando envías una aplicación, Android puede acceder a todo lo que se muestre o se reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"El Asistente está activado"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Configura la aplicación de notas predeterminada en Ajustes"</string> <string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono y cámara"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso reciente en aplicaciones"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso reciente"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 3817e78fa686..988d4d745494 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Teine seade taotles süsteemi keele muutmist"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Muuda keelt"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Kasuta praegust keelt"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"WiFi jagamine"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Kas lubada selles võrgus juhtmevaba silumine?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Võrgu nimi (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWiFi-võrgu aadress (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Luba selles võrgus alati"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Vale muster"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Vale parool"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Liiga palju valesid katseid.\nProovige <xliff:g id="NUMBER">%d</xliff:g> sekundi pärast uuesti."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Hädaabi"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Proovige uuesti. Katse <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Teie andmed kustutatakse"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Kui sisestate järgmisel katsel vale mustri, kustutatakse selle seadme andmed."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kui jagate, salvestate või kannate üle, on rakendusel <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kui jagate, salvestate või kannate rakendust üle, on rakendusel <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> juurdepääs kõigele, mida selles rakenduses kuvatakse või esitatakse. Seega olge paroolide, makseteabe, sõnumite, fotode, heli ja videoga ettevaatlik."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Alusta"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on selle valiku keelanud"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Kas alustada ülekandmist?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kui kannate üle, on Androidil juurdepääs kõigele, mis on teie ekraanikuval nähtaval või mida teie seadmes esitatakse. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Rakenduse ülekandmise ajal on Androidil juurdepääs kõigele, mis on selles rakenduses nähtaval või mida selles esitatakse. Seega olge paroolide, makseteabe, sõnumite, fotode, heli ja videoga ettevaatlik."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent on aktiveeritud"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Määrake seadetes märkmete vaikerakendus."</string> <string name="install_app" msgid="5066668100199613936">"Installi rakendus"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ja kaamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Rakenduste hiljutine kasutamine"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Kuva hiljutine juurdepääs"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 2ad43cc86ddd..71cb074dc599 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Beste gailu batek sistemaren hizkuntza aldatzeko eskatu du"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Aldatu hizkuntza"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mantendu oraingo hizkuntza"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Partekatu wifia"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Hari gabeko arazketa sare honetan erabiltzeko baimena eman nahi duzu?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Sarearen izena (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWifi-helbidea (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Eman baimena beti sare honetan"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Eredua ez da zuzena"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pasahitza ez da zuzena"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Saiakera oker gehiegi egin dituzu.\nSaiatu berriro <xliff:g id="NUMBER">%d</xliff:g> segundo barru."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Larrialdi-deia"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Saiatu berriro. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> saiakera."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Datuak ezabatuko dira"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Hurrengo saiakeran eredua oker marrazten baduzu, gailuko datuak ezabatuko dira."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Edukia partekatzen, grabatzen edo igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Aplikazio bat partekatzen, grabatzen edo igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Hasi"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak aukera desgaitu du"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Igortzen hasi nahi duzu?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Edukia igortzen ari zarenean, pantailan ikusgai dagoen edo gailuan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Aplikazio bat igortzen ari zarenean, aplikazio horretan ikusgai dagoen edo bertan erreproduzitzen ari den guztia atzi dezake Android-ek. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Laguntzailea zerbitzuak arreta jarrita dauka"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ezarri oharren aplikazio lehenetsia ezarpenetan"</string> <string name="install_app" msgid="5066668100199613936">"Instalatu aplikazioa"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonoa eta kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azken erabilera"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ikusi azkenaldiko sarbidea"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 8263639a4fc1..8902103c4399 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"دستگاه دیگری درخواست کرده است زبان سیستم تغییر کند"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"تغییر زبان"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"حفظ زبان فعلی"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"اشتراکگذاری Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"اشکالزدایی بیسیم در این شبکه مجاز شود؟"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"نام شبکه (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nنشانی Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"همیشه در این شبکه مجاز شود"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"الگو اشتباه است"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"گذرواژه اشتباه است"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"تلاشهای نادرست بسیاری انجام شده است.\nپس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"اضطراری"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"دوباره امتحان کنید. تلاش <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> از <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"دادههایتان حذف خواهد شد"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"اگر در تلاش بعدی الگوی نادرستی وارد کنید، دادههای این دستگاه حذف خواهد شد."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"وقتی درحال همرسانی، ضبط، یا پخش محتوا هستید، <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> به همه محتوایی که در صفحهتان نمایان است یا در دستگاهتان پخش میشود دسترسی دارد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"وقتی درحال همرسانی، ضبط، یا پخش محتوای برنامهای هستید، <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> به همه محتوایی که در آن برنامه نمایان است یا پخش میشود دسترسی دارد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"شروع"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>این گزینه را غیرفعال کرده است"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"پخش محتوا شروع شود؟"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"وقتی محتوا پخش میکنید، Android به همه محتوایی که در صفحهتان نمایان است یا در دستگاهتان پخش میشود دسترسی دارد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"وقتی محتوای برنامهای را پخش میکنید، Android به همه محتوایی که در آن برنامه نمایان است یا پخش میشود دسترسی دارد. درنتیجه مراقب چیزهایی مثل گذرواژهها، جزئیات پرداخت، پیامها، عکسها، و صدا و تصویر باشید."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"توجه «دستیار» روشن است"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"برنامه پیشفرض یادداشت را در «تنظیمات» تنظیم کنید"</string> <string name="install_app" msgid="5066668100199613936">"نصب برنامه"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"میکروفون و دوربین"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"استفاده اخیر از برنامه"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"دیدن دسترسی اخیر"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index dc0e52de6217..7e2ab650f037 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Toiselta laitteelta pyydetty järjestelmän kielen vaihtamista"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Vaihda kieltä"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Pidä nykyinen kieli"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Jaa Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Sallitaanko langaton virheenkorjaus tässä verkossa?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Verkon nimi (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi-Fin osoite (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Salli aina tässä verkossa"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Väärä kuvio"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Väärä salasana"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Liian monta virheellistä yritystä.\nYritä uudelleen <xliff:g id="NUMBER">%d</xliff:g> sekunnin kuluttua."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Hätätilanne"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Yritä uudelleen. Yritys <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Datasi poistetaan"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Jos annat väärän kuvion seuraavalla yrityskerralla, tämän laitteen data poistetaan."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kun jaat, tallennat tai striimaat, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> saa pääsyn kaikkeen näytölläsi näkyvään tai laitteellasi toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kun jaat, tallennat tai striimaat sovellusta, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> saa pääsyn kaikkeen sovelluksessa näkyvään tai toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Aloita"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on poistanut vaihtoehdon käytöstä"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Aloitetaanko striimaus?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kun striimaat, Android saa pääsyn kaikkeen näytölläsi näkyvään tai laitteellasi toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kun striimaat sovellusta, Android saa pääsyn kaikkeen sovelluksessa näkyvään tai toistettuun sisältöön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant on aktiivinen"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Aseta oletusmuistiinpanosovellus Asetuksista"</string> <string name="install_app" msgid="5066668100199613936">"Asenna sovellus"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni ja kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Sovellusten viimeaikainen käyttö"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Katso viimeaikainen käyttö"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index dcaaef0c5b53..a863623df8d1 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Un autre appareil demande de changer la langue du système"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Changer la langue"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Garder la langue actuelle"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Partager le Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Autoriser le débogage sans fil sur ce réseau?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nom du réseau (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresse Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Toujours autoriser sur ce réseau"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Schéma incorrect"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Mot de passe incorrect"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Trop de tentatives incorrectes. \nRéessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Appel d\'urgence"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Réessayez. Tentative <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> sur <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vos données seront supprimées"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Si vous entrez un schéma incorrect à la prochaine tentative, les données de cet appareil seront supprimées."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou diffusez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une application, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Commencer"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Commencer la diffusion?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Lorsque vous diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant à l\'écoute"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string> <string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone et appareil photo"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applications"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Afficher l\'accès récent"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 0fbf014e57c3..a3920de7bf9e 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Changement de langue système demandé par un autre appareil"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Changer de langue"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Garder la langue actuelle"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Partager le Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Autoriser le débogage sans fil sur ce réseau ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nom du réseau (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresse Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Toujours autoriser sur ce réseau"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Schéma incorrect"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Mot de passe incorrect"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Trop de tentatives incorrectes.\nVeuillez réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Urgence"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Réessayez. Tentative <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> sur <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Risque de perte des données"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Si vous dessinez un schéma incorrect lors de la prochaine tentative, les données de cet appareil seront supprimées."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou castez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou castez une appli, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages et contenus audio et vidéo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Commencer"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Commencer à caster ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Lorsque vous castez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous castez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages et contenus audio et vidéo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant à l\'écoute"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir une appli de notes par défaut dans les paramètres"</string> <string name="install_app" msgid="5066668100199613936">"Installer l\'appli"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micro et caméra"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applis"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consulter les accès récents"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 27b57e419aa8..344c0d4191f6 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Outro dispositivo solicitou un cambio do idioma do sistema"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambiar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Manter idioma actual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Compartir wifi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Queres permitir a depuración sen fíos nesta rede?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nome de rede (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nEnderezo wifi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir sempre nesta rede"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"O padrón é incorrecto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"O contrasinal é incorrecto"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Realizáronse demasiados intentos incorrectos.\nTéntao de novo en <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emerxencia"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Téntao de novo. Intento <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Eliminaranse os teus datos"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Se indicas un padrón incorrecto no seguinte intento, eliminaranse os datos deste dispositivo."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Cando compartes, gravas ou emites contido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ten acceso a todo o que se vexa na pantalla ou se reproduza no teu dispositivo. Polo tanto, debes ter coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como o contido de audio e de vídeo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Cando compartes, gravas ou emites unha aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ten acceso a todo o que se vexa ou se reproduza nela. Polo tanto, debes ter coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como o contido de audio e de vídeo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Iniciar"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> desactivou esta opción"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Queres comezar a emitir contido?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Cando emites contido, Android ten acceso a todo o que se vexa na pantalla ou se reproduza no teu dispositivo. Polo tanto, debes ter coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como o contido de audio e de vídeo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Cando emites unha aplicación, Android ten acceso a todo o que se vexa ou se reproduza nela. Polo tanto, debes ter coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como o contido de audio e de vídeo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"A atención do Asistente está activada"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Establece a aplicación de notas predeterminada en Configuración"</string> <string name="install_app" msgid="5066668100199613936">"Instalar aplicación"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micrófono e cámara"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente por parte de aplicacións"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acceso recente"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index d62fd9986575..a32c78fce8bb 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"બીજા ડિવાઇસ દ્વારા સિસ્ટમની ભાષા બદલવાની વિનંતી કરવામાં આવી છે"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ભાષા બદલો"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"વર્તમાન ભાષા રાખો"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"વાઇ-ફાઇ શેર કરો"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"આ નેટવર્ક પર વાયરલેસ ડિબગીંગની મંજૂરી આપીએ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"નેટવર્કનું નામ (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nવાઇ-ફાઇ ઍડ્રેસ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"આ નેટવર્ક પર હંમેશા મંજૂરી આપો"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ખોટી પૅટર્ન"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ખોટો પાસવર્ડ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ઘણા વધારે ખોટા પ્રયત્નો. \n <xliff:g id="NUMBER">%d</xliff:g> સેકંડમાં ફરી પ્રયાસ કરો."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ઇમર્જન્સી"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ફરી પ્રયાસ કરો. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> માંથી <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> પ્રયત્ન."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"તમારો ડેટા ડિલીટ કરવામાં આવશે"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"જો તમે આગલા પ્રયત્નમાં ખોટી પૅટર્ન દાખલ કરશો, તો આ ડિવાઇસનો ડેટા ડિલીટ કરવામાં આવશે."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"જ્યારે તમે શેર, રેકોર્ડ અથવા કાસ્ટ કરી રહ્યાં હો, ત્યારે તમારી સ્ક્રીન પર દેખાતી હોય કે તમારા ડિવાઇસ પર ચલાવવામાં આવતી હોય તેવી બધી વસ્તુનો ઍક્સેસ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> પાસે હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"જ્યારે તમે કોઈ ઍપ શેર, રેકોર્ડ અથવા કાસ્ટ કરી રહ્યાં હો, ત્યારે તે ઍપ પર બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુનો ઍક્સેસ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> પાસે હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"શરૂ કરો"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> દ્વારા આ વિકલ્પ બંધ કરવામાં આવ્યો છે"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"કાસ્ટ કરવાનું શરૂ કરીએ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"જ્યારે તમે કાસ્ટ કરી રહ્યાં હો, ત્યારે તમારી સ્ક્રીન પર દેખાતી કે તમારા ડિવાઇસ પર ચલાવવામાં આવતી બધી વસ્તુઓનો ઍક્સેસ Android પાસે હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"જ્યારે તમે ઍપને કાસ્ટ કરી રહ્યાં હો, ત્યારે તે ઍપ પર બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુનો ઍક્સેસ Android પાસે હોય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant સક્રિય છે"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"સેટિંગમાં નોંધની ડિફૉલ્ટ ઍપ સેટ કરો"</string> <string name="install_app" msgid="5066668100199613936">"ઍપ ઇન્સ્ટૉલ કરો"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"માઇક્રોફોન અને કૅમેરા"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"તાજેતરનો ઍપનો વપરાશ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"તાજેતરનો ઍક્સેસ મેનેજ કરો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 18774aeddef6..c73b8f79c873 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"किसी दूसरे डिवाइस से, सिस्टम की भाषा बदलने का अनुरोध किया गया"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा बदलें"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"मौजूदा भाषा रखें"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"वाई-फ़ाई शेयर करें"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"क्या आप इस नेटवर्क पर वॉयरलेस डीबगिंग के इस्तेमाल की अनुमति देना चाहते हैं?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"नेटवर्क का नाम (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nवाई-फ़ाई का पता (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"इस नेटवर्क पर हमेशा अनुमति दें"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"गलत पैटर्न"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"गलत पासवर्ड"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"आपकी कोशिशें बहुत बार गलत हुई हैं.\nआप <xliff:g id="NUMBER">%d</xliff:g> सेकंड में फिर से कोशिश कर सकते हैं."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"आपातकालीन कॉल"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"फिर से कोशिश करें. आप <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> में से <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> बार कोशिश कर चुके हैं."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"आपका डेटा मिटा दिया जाएगा"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"अगर आप फिर से गलत पैटर्न डालते हैं, तो इस डिवाइस का डेटा मिटा दिया जाएगा."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"किसी ऐप्लिकेशन को शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास उस ऐप्लिकेशन पर दिख रहे कॉन्टेंट या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"शुरू करें"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ने इस विकल्प को बंद कर दिया है"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"क्या मीडिया कास्ट करना है?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"कास्ट करते समय, Android के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"किसी ऐप्लिकेशन को कास्ट करते समय, Android के पास उस ऐप्लिकेशन पर दिख रहे कॉन्टेंट या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant आपकी बातें सुन रही है"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग में जाकर, नोट लेने की सुविधा देने वाले ऐप्लिकेशन को डिफ़ॉल्ट के तौर पर सेट करें"</string> <string name="install_app" msgid="5066668100199613936">"ऐप्लिकेशन इंस्टॉल करें"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफ़ोन और कैमरा"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"हाल ही में इस्तेमाल करने वाला ऐप्लिकेशन"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"हाल में ऐक्सेस करने वाले ऐप"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index b6840383da38..f9b220ddb9f1 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Drugi uređaj zatražio je promjenu jezika sustava"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Promijeni jezik"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zadrži trenutačni jezik"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Dijeli Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Dopustiti bežično otklanjanje pogrešaka na ovoj mreži?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fija (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dopusti na ovoj mreži"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pogrešan uzorak"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Pogrešna zaporka"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Previše netočnih pokušaja.\nPokušajte ponovo za <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Hitni slučaj"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Pokušajte ponovo. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. pokušaj od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vaši će se podaci izbrisati"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ako pri sljedećem pokušaju unesete netočan uzorak, izbrisat će se podaci s ovog uređaja."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kad dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pokreni"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućila je ovu opciju"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite li pokrenuti emitiranje?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kad emitirate, Android ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kad emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pažnja Asistenta je aktivirana"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Postavite zadanu aplikaciju za bilješke u postavkama"</string> <string name="install_app" msgid="5066668100199613936">"Instalacija"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna upotreba aplikacije"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Pogledajte nedavni pristup"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 26f60f9ac69b..0d40770bb939 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Egy másik eszköz a rendszer nyelvének módosítását kéri"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Nyelvmódosítás"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Aktuális nyelv megtartása"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi megosztása"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Engedélyezi a vezeték nélküli hibakeresést ezen a hálózaton?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Hálózat neve (SSID):\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-cím (BSSID):\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Mindig engedélyezze ezen a hálózaton"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Helytelen minta"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Helytelen jelszó"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Túl sok helytelen próbálkozás.\nPróbálja újra <xliff:g id="NUMBER">%d</xliff:g> másodperc múlva."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Vészhelyzet"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Próbálja újra. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. kísérlet, összesen: <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Adatai törlődni fognak"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Amennyiben helytelen mintát ad meg a következő kísérletnél, a rendszer törli az adatokat erről az eszközről."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Amikor Ön megosztást, rögzítést vagy átküldést végez, a(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a képernyőn látható vagy az eszközön lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Amikor Ön megoszt, rögzít vagy átküld egy alkalmazást, a(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> az adott appban látható vagy lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Indítás"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> letiltotta ezt a beállítást"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Elindítja az átküldést?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Amikor Ön átküldést végez, az Android a képernyőn látható vagy az eszközön lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Alkalmazás átküldése közben az Android az adott appban látható vagy lejátszott minden tartalomhoz hozzáfér. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"A Segéd figyel"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Állítson be alapértelmezett jegyzetkészítő alkalmazást a Beállításokban"</string> <string name="install_app" msgid="5066668100199613936">"Alkalmazás telepítése"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon és kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Legutóbbi alkalmazáshasználat"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Legutóbbi hozzáférés"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index da38ae11a457..e64a8de3b638 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Մեկ այլ սարք համակարգի լեզվի փոփոխության հարցում է ուղարկել"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Փոխել լեզուն"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Թողնել ընթացիկ լեզուն"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Կիսվել Wi‑Fi-ով"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Թույլատրե՞լ անլար վրիպազերծումն այս ցանցում"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Ցանցի անվանումը (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-ի հասցեն (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Միշտ թույլատրել այս ցանցում"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Նախշը սխալ է"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Գաղտնաբառը սխալ է"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Չափից շատ սխալ փորձ է կատարվել:\nՆորից փորձեք <xliff:g id="NUMBER">%d</xliff:g> վայրկյանից:"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Արտակարգ իրավիճակ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Փորձեք նորից։ Փորձ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>՝ <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>-ից։"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Ձեր տվյալները կջնջվեն"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Հաջորդ փորձի ժամանակ սխալ նախշ մուտքագրելու դեպքում սարքի տվյալները կջնջվեն։"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Երբ դուք ցուցադրում, տեսագրում կամ հեռարձակում եք էկրանը, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին հասանելի է լինում այն ամենը, ինչ տեսանելի է ձեր էկրանին և նվագարկվում է ձեր սարքում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Երբ դուք ցուցադրում, տեսագրում կամ հեռարձակում եք որևէ հավելվածի էկրանը, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին հասանելի է լինում այն ամենը, ինչ ցուցադրվում կամ նվագարկվում է այդ հավելվածում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Սկսել"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ն անջատել է այս ընտրանքը"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Սկսե՞լ հեռարձակումը"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Երբ դուք հեռարձակում եք էկրանը, Android-ին հասանելի է լինում այն ամենը, ինչ տեսանելի է ձեր էկրանին կամ նվագարկվում է ձեր սարքում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Երբ դուք տեսագրում եք որևէ հավելվածի էկրանը, Android-ին հասանելի է լինում այն ամենը, ինչ ցուցադրվում կամ նվագարկվում է այդ հավելվածում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Օգնականը լսում է"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Կարգավորեք նշումների կանխադրված հավելված Կարգավորումներում"</string> <string name="install_app" msgid="5066668100199613936">"Տեղադրել հավելվածը"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Խոսափող և տեսախցիկ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Հավելվածի վերջին օգտագործումը"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Տեսնել վերջին օգտագործումը"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 320e125a9632..d2a974784026 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Perubahan bahasa sistem diminta oleh perangkat lain"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ubah bahasa"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Pertahankan bahasa"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Bagikan Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Izinkan proses debug nirkabel di perangkat ini?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nama Jaringan (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAlamat Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Selalu izinkan di jaringan ini"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Pola salah"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Sandi salah"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Terlalu banyak kesalahan pola.\nCoba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Keadaan Darurat"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Coba lagi. Percobaan <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> dari <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Data akan dihapus"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Jika Anda memasukkan pola yang salah saat mencoba lagi, data perangkat ini akan dihapus."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Jika Anda membagikan, merekam, atau mentransmisikan, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Jika Anda membagikan, merekam, atau mentransmisikan suatu aplikasi, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio dan video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Mulai"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah menonaktifkan opsi ini"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Mulai mentransmisikan?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Jika mentransmisikan, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Jika Anda mentransmisikan aplikasi, Android akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string> @@ -712,7 +709,7 @@ <string name="switch_bar_off" msgid="5669805115416379556">"Nonaktif"</string> <string name="tile_unavailable" msgid="3095879009136616920">"Tidak tersedia"</string> <string name="accessibility_tile_disabled_by_policy_action_description" msgid="6958422730461646926">"pelajari lebih lanjut"</string> - <string name="nav_bar" msgid="4642708685386136807">"Bilah navigasi"</string> + <string name="nav_bar" msgid="4642708685386136807">"Menu navigasi"</string> <string name="nav_bar_layout" msgid="4716392484772899544">"Tata letak"</string> <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Jenis tombol ekstra kiri"</string> <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Jenis tombol ekstra kanan"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asisten sedang memerhatikan"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setel aplikasi catatan default di Setelan"</string> <string name="install_app" msgid="5066668100199613936">"Instal aplikasi"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon & Kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Penggunaan aplikasi baru-baru ini"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Lihat akses terbaru"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 73f17453fe2f..d5bb28a87afd 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Beiðni frá öðru tæki um að breyta tungumáli kerfis"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Breyta tungumáli"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Halda núverandi tungumáli"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Deila Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Viltu leyfa þráðlausa villuleit á þessu neti?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Heiti netkerfis (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi vistfang (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Leyfa alltaf á þessu neti"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Rangt mynstur"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Rangt aðgangsorð"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Of margar misheppnaðar tilraunir.\nReyndu aftur eftir <xliff:g id="NUMBER">%d</xliff:g> sekúndur."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Neyðartilvik"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Reyndu aftur. Tilraun <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> af <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Gögnunum þínum verður eytt"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ef þú slærð inn rangt mynstur í næstu tilraun verður gögnum tækisins eytt."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Þegar þú deilir, tekur upp eða varpar hefur<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aðgang að öllu sem sést á skjánum eða spilast í tækinu. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Þegar þú deilir, tekur upp eða varpar forriti hefur <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aðgang að öllu sem sést eða spilast í viðkomandi forriti. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Byrja"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> slökkti á þessum valkosti"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Byrja að varpa?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Þegar þú varpar hefur Android aðgang að öllu sem er sýnilegt á skjánum hjá þér eða spilast í tækinu þínu. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Þegar þú varpar forriti hefur Android aðgang að öllu sem sést eða spilast í viðkomandi forriti. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Hjálparinn er að hlusta"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Stilltu sjálfgefið glósuforrit í stillingunum"</string> <string name="install_app" msgid="5066668100199613936">"Setja upp forrit"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Hljóðnemi og myndavél"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nýlega notað af forriti"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Sjá nýlegan aðgang"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 0db6d7f9a3cf..9f6228d549b7 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Cambio della lingua di sistema richiesto da un altro dispositivo"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Cambia lingua"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mantieni lingua attuale"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Condividi Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Consentire il debug wireless su questa rete?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nome della rete (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nIndirizzo Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Consenti sempre su questa rete"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Sequenza errata"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Password errata"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Troppi tentativi errati.\nRiprova tra <xliff:g id="NUMBER">%d</xliff:g> secondi."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergenza"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Riprova. Tentativo <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> di <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"I tuoi dati verranno eliminati"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Se al prossimo tentativo inserirai una sequenza sbagliata, i dati del dispositivo verranno eliminati."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quando condividi, registri o trasmetti, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ha accesso a qualsiasi elemento visibile sul tuo schermo o in riproduzione sul tuo dispositivo. Presta quindi attenzione a password, dettagli sui pagamenti, messaggi, foto, audio e video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quando condividi, registri o trasmetti un\'app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ha accesso a qualsiasi elemento visualizzato o riprodotto sull\'app. Presta quindi attenzione a password, dettagli sui pagamenti, messaggi, foto, audio e video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Inizia"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha disattivato questa opzione"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Iniziare a trasmettere?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Quando trasmetti, Android ha accesso a qualsiasi elemento visibile sul tuo schermo o in riproduzione sul tuo dispositivo. Presta quindi attenzione a password, dettagli sui pagamenti, messaggi, foto, audio e video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Quando trasmetti un\'app, Android ha accesso a qualsiasi elemento visualizzato o riprodotto sull\'app. Presta quindi attenzione a password, dettagli sui pagamenti, messaggi, foto, audio e video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"L\'assistente è attivo"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Imposta l\'app per le note predefinita nelle Impostazioni"</string> <string name="install_app" msgid="5066668100199613936">"Installa app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfono e fotocamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente da app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vedi accesso recente"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 053963543bfc..44ad4452e808 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"התקבלה בקשה ממכשיר אחר לשינוי שפת המערכת"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"שינוי שפה"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"השארת השפה הנוכחית"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"שיתוף Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"לאשר ניפוי באגים אלחוטי ברשת הזו?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"שם הרשת (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nכתובת Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"לאשר תמיד ברשת הזו"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"קו ביטול נעילה שגוי"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"סיסמה שגויה"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"יותר מדי ניסיונות שגויים.\nיש לנסות שוב בעוד <xliff:g id="NUMBER">%d</xliff:g> שניות."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"חירום"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"יש לנסות שוב. ניסיון <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> מתוך <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"הנתונים שלך יימחקו"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"הזנת קו ביטול נעילה שגוי בניסיון הבא תגרום למחיקת הנתונים במכשיר."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"בזמן שיתוף, הקלטה או העברה (cast) תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה ל-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"התחלה"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> השביתה את האפשרות הזו"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"להתחיל את ההעברה?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"בזמן העברה (cast), תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"בזמן העברה (cast) של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant מאזינה"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"צריך להגדיר את אפליקציית ברירת המחדל לפתקים ב\'הגדרות\'"</string> <string name="install_app" msgid="5066668100199613936">"התקנת האפליקציה"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"מיקרופון ומצלמה"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"נעשה שימוש לאחרונה באפליקציות"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"צפייה בהרשאות הגישה האחרונות"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 967d2d1818e5..5bd77fc5df48 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"他のデバイスからシステム言語の変更が要求されました"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"言語を変更"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"現在の言語を変更しない"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi-Fi を共有"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"このネットワークでワイヤレス デバッグを許可しますか?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ネットワーク名(SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi アドレス(BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"このネットワークで常に許可する"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"パターンが正しくありません"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"パスワードが正しくありません"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"間違えた回数が上限を超えました。\n<xliff:g id="NUMBER">%d</xliff:g> 秒後にもう一度お試しください。"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"緊急通報"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"もう一度お試しください。入力回数: <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 回"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"データが削除されます"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"パターンをあと 1 回間違えると、このデバイスのデータが削除されます。"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"共有、録画、キャスト中は、画面に表示される内容やデバイスで再生される内容に <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"アプリの共有、録画、キャスト中は、そのアプリで表示または再生される内容に <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"開始"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> がこのオプションを無効にしています"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"キャスト開始しますか?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"キャスト中は、画面に表示される内容やデバイスで再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"アプリのキャスト中は、そのアプリで表示または再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"アシスタントは起動済みです"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"[設定] でデフォルトのメモアプリを設定してください"</string> <string name="install_app" msgid="5066668100199613936">"アプリをインストール"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"マイクとカメラ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"最近のアプリの使用状況"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"最近のアクセスを表示"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 2a30da73c0d7..e0aa8ca955c7 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"სისტემის ენის შეცვლა მოითხოვა სხვა მოწყობილობამ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ენის შეცვლა"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"მიმდინარე ენის დატოვება"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi-ს გაზიარება"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"დაუშვებთ ამ ქსელში შეცდომების უსადენო გამართვას?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ქსელის სახელი (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi მისამართი (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ყოველთვის დაშვება ამ ქსელში"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ნიმუში არასწორია"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"პაროლი არასწორია"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"დაფიქსირდა ძალიან ბევრი არასწორი მცდელობა.\nცადეთ ხელახლა <xliff:g id="NUMBER">%d</xliff:g> წამში."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"საგანგებო სიტუაცია"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ცადეთ ხელახლა. მცდელობა <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> / <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>-დან."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"თქვენი მონაცემები წაიშლება"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"შემდეგი მცდელობისას განმბლოკავი ნიმუშის არასწორად შეყვანის შემთხვევაში, ამ მოწყობილობის მონაცემები წაიშლება."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"გაზიარების, ჩაწერის ან ტრანსლირების დროს, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენს მოწყობილობაზე. ამიტომ იყავით ფრთხილად ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"აპის გაზიარებისას, ჩაწერისას ან ტრანსლირებისას, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-ს წვდომა აქვს ყველაფერზე, რაც ჩანს ან იკვრება აპში. ამიტომ იყავით ფრთხილად ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"დაწყება"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-მა გათიშა ეს ვარიანტი"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"გსურთ ტრანსლირების დაწყება?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"როდესაც თქვენ ტრანსლირებთ, ამ აპს აქვს წვდომა ყველაფერზე, რაც ჩანს თქვენს ეკრანზე ან უკრავს თქვენს მოწყობილობაზე. ამიტომ იყავით ფრთხილად ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"როდესაც აპს ტრანსლირებთ, Android-ს წვდომა აქვს ყველაფერზე, რაც ჩანს ან იკვრება აპში. ამიტომ იყავით ფრთხილად ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"ასისტენტის ყურადღების ფუნქცია ჩართულია"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"დააყენეთ ნაგულისხმევი შენიშვნების აპი პარამეტრებში"</string> <string name="install_app" msgid="5066668100199613936">"აპის ინსტალაცია"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"აირეკლოს გარე ეკრანზე?"</string> + <string name="enable_display" msgid="8308309634883321977">"ეკრანის ჩართვა"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"მიკროფონი და კამერა"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"აპის ბოლოდროინდელი გამოყენება"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ბოლო წვდომის ნახვა"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 1adda91ee5da..917383bc4979 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Басқа құрылғыдан жүйе тілін өзгерту туралы сұрау жіберілді."</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Тілді өзгерту"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Қазіргі тіл тұра берсін"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi желісін бөлісу"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Бұл желіде сымсыз түзетуге рұқсат етілсін бе?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Желі атауы (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi мекенжайы (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Осы желіде үнемі рұқсат ету"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Өрнек қате."</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Құпия сөз қате."</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Тым көп қате енгізілді.\n<xliff:g id="NUMBER">%d</xliff:g> секундта әрекетті қайталаңыз."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Төтенше жағдай"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Әрекетті қайталаңыз. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> мүмкіндік, барлығы – <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Деректеріңіз жойылады"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Келесі әрекет кезінде қате өрнек енгізсеңіз, бұл құрылғылардың деректері жойылады."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Бөлісу, жазу не трансляциялау кезінде <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Қолданба экранын бөлісу, жазу не трансляциялау кезінде <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> онда көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Бастау"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы осы опцияны өшірді."</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Трансляциялау басталсын ба?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Трансляциялау кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Қолданба экранын трансляциялау кезінде Android жүйесі қолданбада көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant қосулы."</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден әдепкі жазба қолданбасын орнатыңыз."</string> <string name="install_app" msgid="5066668100199613936">"Қолданбаны орнату"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон және камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Соңғы рет қолданбаның датчикті пайдалануы"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Соңғы рет пайдаланғандар"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index af1e3b500e54..92c2c1b35c73 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ការប្ដូរភាសាប្រព័ន្ធដែលបានស្នើសុំដោយឧបករណ៍ផ្សេងទៀត"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ប្ដូរភាសា"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"រក្សាភាសាបច្ចុប្បន្ន"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ចែករំលែក Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"អនុញ្ញាតការជួសជុលដោយឥតខ្សែនៅលើបណ្ដាញនេះឬ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ឈ្មោះបណ្ដាញ (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nអាសយដ្ឋាន Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"អនុញ្ញាតនៅលើបណ្ដាញនេះជានិច្ច"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"លំនាំមិនត្រឹមត្រូវ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ពាក្យសម្ងាត់មិនត្រឹមត្រូវ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ការព្យាយាមចូលខុសច្រើនដងពេក។\nសូមព្យាយាមម្តងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER">%d</xliff:g> វិនាទី។"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ពេលមានអាសន្ន"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"សូមព្យាយាមម្តងទៀត។ ការព្យាយាម <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> នៃ <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> ដង។"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ទិន្នន័យរបស់អ្នកនឹងត្រូវបានលុប"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ប្រសិនបើអ្នកបញ្ចូលលំនាំមិនត្រឹមត្រូវ នៅពេលព្យាយាមបញ្ចូលលើកក្រោយ ទិន្នន័យរបស់ឧបករណ៍នេះនឹងត្រូវបានលុប។"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"នៅពេលអ្នកកំពុងចែករំលែក ថត ឬភ្ជាប់, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មានសិទ្ធិចូលប្រើអ្វីៗដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬចាក់នៅលើឧបករណ៍របស់អ្នក។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"នៅពេលអ្នកកំពុងចែករំលែក ថត ឬភ្ជាប់កម្មវិធី, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មានសិទ្ធិចូលប្រើអ្វីៗដែលបង្ហាញ ឬចាក់នៅលើកម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ចាប់ផ្ដើម"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> បានបិទជម្រើសនេះ"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ចាប់ផ្តើមភ្ជាប់ឬ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"នៅពេលអ្នកកំពុងភ្ជាប់, Android មានសិទ្ធិចូលប្រើអ្វីៗដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬចាក់នៅលើឧបករណ៍របស់អ្នក។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"នៅពេលអ្នកកំពុងភ្ជាប់កម្មវិធី, Android មានសិទ្ធិចូលប្រើអ្វីៗដែលបង្ហាញ ឬចាក់នៅលើកម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"ភាពប្រុងប្រៀបរបស់ Google Assistant ត្រូវបានបើក"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"កំណត់កម្មវិធីកំណត់ចំណាំលំនាំដើមនៅក្នុងការកំណត់"</string> <string name="install_app" msgid="5066668100199613936">"ដំឡើងកម្មវិធី"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"មីក្រូហ្វូន និងកាមេរ៉ា"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ការប្រើប្រាស់កម្មវិធីថ្មីៗនេះ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"មើលការចូលប្រើនាពេលថ្មីៗនេះ"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index db1b35dfaf43..6c0f833b563b 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ಬೇರೊಂದು ಸಾಧನದಿಂದ ಸಿಸ್ಟಮ್ ಭಾಷೆಯ ಬದಲಾವಣೆಯನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ಭಾಷೆಯನ್ನು ಬದಲಾಯಿಸಿ"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ಪ್ರಸ್ತುತ ಭಾಷೆಯನ್ನೇ ಇರಿಸಿ"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ವೈ-ಫೈ ಹಂಚಿಕೊಳ್ಳಿ"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ಈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸಬೇಕೆ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ನೆಟ್ವರ್ಕ್ ಹೆಸರು (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nವೈ-ಫೈ ವಿಳಾಸ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ಈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಅನುಮತಿಸಿ"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ಪ್ಯಾಟರ್ನ್ ತಪ್ಪಾಗಿದೆ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ಪಾಸ್ವರ್ಡ್ ತಪ್ಪಾಗಿದೆ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ಹಲವಾರು ತಪ್ಪು ಪ್ರಯತ್ನಗಳು.\nಮತ್ತೆ <xliff:g id="NUMBER">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ತುರ್ತು"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> ಪ್ರಯತ್ನಗಳು."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ಮುಂದಿನ ಪ್ರಯತ್ನದಲ್ಲಿ ನೀವು ತಪ್ಪಾದ ಪ್ಯಾಟರ್ನ್ ನಮೂದಿಸಿದರೆ, ಈ ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"ನೀವು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ಪ್ರಾರಂಭಿಸಿ"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ಕ್ಯಾಸ್ಟ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಬೇಕೇ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ನೀವು ಕ್ಯಾಸ್ಟ್ ಮಾಡುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್ವರ್ಡ್ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ನಿಮ್ಮ ಮಾತನ್ನು ಆಲಿಸುತ್ತಿದೆ"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಡೀಫಾಲ್ಟ್ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಅನ್ನು ಸೆಟ್ ಮಾಡಿ"</string> <string name="install_app" msgid="5066668100199613936">"ಆ್ಯಪ್ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಕ್ಯಾಮರಾ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್ ಬಳಕೆ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ಇತ್ತೀಚಿನ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ನೋಡಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 97271c580103..491c4e47073f 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"다른 기기에서 시스템 언어 변경을 요청함"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"언어 변경"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"현재 언어 유지"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi 공유"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"이 네트워크에서 무선 디버깅을 허용하시겠습니까?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"네트워크 이름(SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi 주소(BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"이 네트워크에서 항상 허용"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"잘못된 패턴"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"잘못된 비밀번호"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"잘못된 시도 횟수가 너무 많습니다.\n<xliff:g id="NUMBER">%d</xliff:g>초 후에 다시 시도하세요."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"긴급"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"다시 시도하세요. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>회 중 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>번째 시도입니다."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"데이터가 삭제됨"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"다음번 시도에서 잘못된 패턴을 입력하면 이 기기의 데이터가 삭제됩니다."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"공유, 녹화 또는 전송 중에 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 앱이 화면에 표시되거나 기기에서 재생되는 모든 항목에 액세스할 수 있습니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"앱을 공유, 녹화 또는 전송할 때는 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 앱이 해당 앱에 표시되거나 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"시작"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 이 옵션을 사용 중지했습니다."</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"전송을 시작하시겠습니까?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"전송 중에는 Android가 화면에 표시되거나 기기에서 재생되는 모든 항목에 액세스할 수 있습니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"앱을 전송할 때 Android가 해당 앱에 표시되거나 재생되는 모든 항목에 액세스할 수 있으므로 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"어시스턴트가 대기 중임"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"설정에서 기본 메모 앱 설정"</string> <string name="install_app" msgid="5066668100199613936">"앱 설치"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"마이크 및 카메라"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"최근 앱 사용"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"최근 액세스 보기"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index db47e39a5de1..77e4e9c7c844 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Система тилин өзгөртүү сурамы башка түзмөктөн жөнөтүлдү"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Тилди өзгөртүү"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Учурдагы тилди калтыруу"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi\'ды бөлүшүү"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Ушул тармакта мүчүлүштүктөрдү Wi-Fi аркылуу аныктоого уруксат бересизби?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Тармактын аталышы (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi дареги (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Бул тармакта ар дайым уруксат берилсин"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Графикалык ачкыч туура эмес"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Сырсөз туура эмес"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Өтө көп жолу жаңылдыңыз.\n<xliff:g id="NUMBER">%d</xliff:g> секунддан кийин кайра кайталаңыз."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Шашылыш чалуу"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Кайра кайталаңыз. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> аракеттен <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> аракет калды."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Акыркы аракет калды"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Эгер графикалык ачкычты кийинки жолу туура эмес киргизсеңиз, бул түзмөктүн маалыматы өчүрүлөт."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Бөлүшүп, жаздырып же тышкы экранга чыгарып жатканда <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу экраныңыздагы бардык маалыматты же түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Колдонмону бөлүшүп, жаздырып же тышкы экранга чыгарганда <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Баштоо"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Тышкы экранга чыгаруу башталсынбы?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Тышкы экранга чыгарганда Android экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Колдонмону тышкы экранга чыгарганда Android ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Жардамчы иштетилди"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Параметрлерден демейки кыска жазуулар колдонмосун тууралаңыз"</string> <string name="install_app" msgid="5066668100199613936">"Колдонмону орнотуу"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон жана камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Жакында колдонмолордо иштетилген"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Акыркы пайдалануусун көрүү"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index ff08be17aa31..ec1744168592 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ມີການຮ້ອງຂໍໃຫ້ປ່ຽນພາສາລະບົບໂດຍອຸປະກອນອື່ນ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ປ່ຽນພາສາ"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ໃຊ້ພາສາປັດຈຸບັນ"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ແບ່ງປັນ Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ອະນຸຍາດການດີບັກໄຮ້ສາຍຢູ່ເຄືອຂ່າຍນີ້ບໍ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ຊື່ເຄືອຂ່າຍ (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nທີ່ຢູ່ Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ອະນຸຍາດຕະຫຼອດຢູ່ເຄືອຂ່າຍນີ້"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ຮູບແບບບໍ່ຖືກຕ້ອງ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ມີຄວາມພະຍາຍາມບໍ່ຖືກຕ້ອງຫຼາຍເທື່ອເກີນໄປ.\nກະລຸນາລອງໃໝ່ອີກໃນ <xliff:g id="NUMBER">%d</xliff:g> ວິນາທີ."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ສຸກເສີນ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ກະລຸນາລອງໃໝ່. ຄວາມພະຍາຍາມເທື່ອທີ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ຂໍ້ມູນຂອງທ່ານຈະຖືກລຶບອອກ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ຫາກທ່ານໃສ່ຣູບແບບຜິດໃນຄວາມພະຍາຍາມເທື່ອຕໍ່ໄປ, ອຸປະກອນນີ້ຈະຖືກລຶບຂໍ້ມູນອອກ."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"ເມື່ອທ່ານກຳລັງແບ່ງປັນ, ບັນທຶກ ຫຼື ສົ່ງສັນຍານ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ຈະມີສິດເຂົ້າເຖິງທຸກສິ່ງທີ່ປາກົດຢູ່ໜ້າຈໍຂອງທ່ານ ຫຼື ຫຼິ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ເມື່ອທ່ານກຳລັງແບ່ງປັນ, ບັນທຶກ ຫຼື ສົ່ງສັນຍານແອັບ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ຈະມີສິດເຂົ້າເຖິງທຸກສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ແອັບດັ່ງກ່າວ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ເລີ່ມ"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ປິດການນຳໃຊ້ຕົວເລືອກນີ້ແລ້ວ"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ເລີ່ມການສົ່ງສັນຍານບໍ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ເມື່ອທ່ານກຳລັງສົ່ງສັນຍານ, Android ຈະມີສິດເຂົ້າເຖິງທຸກສິ່ງທີ່ປາກົດຢູ່ໜ້າຈໍຂອງທ່ານ ຫຼື ຫຼິ້ນຢູ່ອຸປະກອນຂອງທ່ານ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ເມື່ອທ່ານກຳລັງສົ່ງສັນຍານແອັບ, Android ຈະມີສິດເຂົ້າເຖິງທຸກສິ່ງທີ່ສະແດງ ຫຼື ຫຼິ້ນຢູ່ແອັບດັ່ງກ່າວ. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"ການເອີ້ນໃຊ້ຜູ້ຊ່ວຍເປີດຢູ່"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ຕັ້ງຄ່າແອັບຈົດບັນທຶກເລີ່ມຕົ້ນໃນການຕັ້ງຄ່າ"</string> <string name="install_app" msgid="5066668100199613936">"ຕິດຕັ້ງແອັບ"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ໄມໂຄຣໂຟນ ແລະ ກ້ອງຖ່າຍຮູບ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ການໃຊ້ແອັບຫຼ້າສຸດ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ເບິ່ງສິດເຂົ້າເຖິງຫຼ້າສຸດ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index d3fc0633550c..e418e1828bfa 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Užklausą dėl sistemos kalbos pakeitimo pateikė kitas įrenginys"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Keisti kalbą"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Palikti dabartinę kalbą"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Bendrinti „Wi‑Fi“"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Leisti belaidžio ryšio derinimą prisijungus prie šio tinklo?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Tinklo pavadinimas (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\n„Wi‑Fi“ adresas (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Visada leisti naudojant šį tinklą"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Netinkamas atrakinimo piešinys"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Netinkamas slaptažodis"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Per daug klaidingų bandymų.\nBandykite dar kartą po <xliff:g id="NUMBER">%d</xliff:g> sek."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Skamb. pagalbos nr."</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Bandykite dar kartą. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> bandymas iš <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Duomenys bus ištrinti"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Jei kitu bandymu nupiešite netinkamą atrakinimo piešinį, šio įrenginio duomenys bus ištrinti."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kai bendrinate, įrašote ar perduodate turinį, „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ gali pasiekti viską, kas rodoma ekrane ar leidžiama įrenginyje. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kai bendrinate, įrašote ar perduodate programą, „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ gali pasiekti viską, kas rodoma ar leidžiama programoje. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pradėti"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Programoje „<xliff:g id="APP_NAME">%1$s</xliff:g>“ ši parinktis išjungta"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Pradėti perdavimą?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kai perduodate turinį, „Android“ gali pasiekti viską, kas rodoma ekrane ar leidžiama įrenginyje. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kai perduodate programą, „Android“ gali pasiekti viską, kas rodoma ar leidžiama toje programoje. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Padėjėjas klauso"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nustatykite numatytąją užrašų programą Nustatymuose"</string> <string name="install_app" msgid="5066668100199613936">"Įdiegti programą"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonas ir fotoaparatas"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Pastarasis programos naudojimas"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Žr. pastarąją prieigą"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index c577473f8b53..4b5fea3050f2 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Sistēmas valodas maiņu pieprasīja cita ierīce."</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Mainīt valodu"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Paturēt pašreizējo valodu"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Koplietot Wi-Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vai atļaut bezvadu atkļūdošanu šajā tīklā?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Tīkla nosaukums (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi adrese (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Vienmēr atļaut šajā tīklā"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Nepareiza kombinācija"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Nepareiza parole"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Pārāk daudz neveiksmīgu mēģinājumu.\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER">%d</xliff:g> sekundēm."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Ārkārtas situācija"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Mēģiniet vēlreiz (<xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. mēģinājums no <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>)."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Jūsu dati tiks dzēsti"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ja nākamajā mēģinājumā ievadīsiet nepareizu kombināciju, dati šajā ierīcē tiks dzēsti."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kopīgošanas, ierakstīšanas vai apraides laikā <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> var piekļūt visam, kas tiek rādīts jūsu ekrānā vai atskaņots jūsu ierīcē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lietotnes kopīgošanas, ierakstīšanas vai apraides laikā <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Sākt"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> tika atspējota šī opcija"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vai sākt apraidi?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Apraides laikā Android var piekļūt visam, kas tiek rādīts jūsu ekrānā vai atskaņots jūsu ierīcē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lietotnes apraides laikā Android var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistents klausās"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Iestatījumos iestatiet noklusējuma piezīmju lietotni."</string> <string name="install_app" msgid="5066668100199613936">"Instalēt lietotni"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofons un kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nesen izmantoja lietotnes"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Skatīt neseno piekļuvi"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index 9d92b5f7acbf..80aa943505ff 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Побарана е промена на системскиот јазик од друг уред"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени го јазикот"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Зачувај го тековниот јазик"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Сподели Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Да се дозволи безжично отстранување грешки на мрежава?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Име на мрежата (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi адреса (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Секогаш дозволувај на оваа мрежа"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Погрешна шема"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Погрешна лозинка"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Премногу погрешни обиди.\nОбидете се повторно за <xliff:g id="NUMBER">%d</xliff:g>секунди."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Итен случај"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Обидете се повторно. Обид <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> од <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Податоците ќе се избришат"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ако внесете погрешна шема при следниот обид, податоците на уредов ќе се избришат."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Кога споделувате, снимате или емитувате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има пристап до сѐ што е видливо на вашиот екран или пуштено на вашиот уред. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Кога споделувате, снимате или емитувате апликација, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Започни"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ја оневозможи опцијава"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Да се започне со емитување?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Кога емитувате, Android има пристап до сѐ што е видливо на вашиот екран или пуштено на вашиот уред. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Додека емитувате апликација, Android има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки фотографии и аудио и видео."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Вниманието на „Помошникот“ е вклучено"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Поставете стандардна апликација за белешки во „Поставки“"</string> <string name="install_app" msgid="5066668100199613936">"Инсталирајте ја апликацијата"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Неодамнешно користење на апликација"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Видете го скорешниот пристап"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index a33eb4b092e7..021607d5508b 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"സിസ്റ്റത്തിന്റെ ഭാഷ മാറ്റാൻ മറ്റൊരു ഉപകരണം അഭ്യർത്ഥിച്ചു"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ഭാഷ മാറ്റുക"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"നിലവിലെ ഭാഷ നിലനിർത്തുക"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"വൈഫൈ പങ്കിടുക"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ഈ നെറ്റ്വർക്കിൽ വയർലെസ് ഡീബഗ്ഗിംഗ് അനുവദിക്കണോ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"നെറ്റ്വർക്കിന്റെ പേര് (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nവൈഫൈ വിലാസം (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ഈ നെറ്റ്വർക്കിൽ എപ്പോഴും അനുവദിക്കുക"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"പാറ്റേൺ തെറ്റാണ്"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"പാസ്വേഡ് തെറ്റാണ്"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"നിരവധി തെറ്റായ ശ്രമങ്ങൾ. \n<xliff:g id="NUMBER">%d</xliff:g> സെക്കൻഡിൽ വീണ്ടും ശ്രമിക്കുക."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"അടിയന്തരം"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"വീണ്ടും ശ്രമിക്കുക. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> ശ്രമങ്ങളിൽ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ശ്രമം."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"നിങ്ങളുടെ ഡാറ്റ ഇല്ലാതാക്കപ്പെടും"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"അടുത്ത തവണയും നിങ്ങൾ തെറ്റായ പാറ്റേൺ നൽകിയാൽ, ഈ ഉപകരണത്തിലെ ഡാറ്റ ഇല്ലാതാക്കപ്പെടും."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"പങ്കിടുമ്പോൾ, റെക്കോർഡ് ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യുമ്പോൾ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ഉപകരണത്തിൽ പ്ലേ ചെയ്യുന്നതോ ആയ ഏത് കാര്യത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ഒരു ആപ്പ് പങ്കിടുമ്പോൾ, റെക്കോർഡ് ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ കാസ്റ്റ് ചെയ്യുമ്പോൾ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ആ ആപ്പിൽ കാണിക്കുന്ന അല്ലെങ്കിൽ പ്ലേ ചെയ്യുന്ന എല്ലാത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ആരംഭിക്കുക"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഈ ഓപ്ഷൻ പ്രവർത്തനരഹിതമാക്കി"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"കാസ്റ്റ് ചെയ്യാൻ ആരംഭിക്കണോ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"നിങ്ങൾ കാസ്റ്റ് ചെയ്യുമ്പോൾ, Android-ന് സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ഉപകരണത്തിൽ പ്ലേ ചെയ്യുന്നതോ ആയ ഏത് കാര്യത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"നിങ്ങൾ ഒരു ആപ്പ് കാസ്റ്റ് ചെയ്യുമ്പോൾ, Android-ന് ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാത്തിലേക്കും ആക്സസ് ഉണ്ട്. അതിനാൽ പാസ്വേഡുകൾ, പേയ്മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങൾ നൽകുമ്പോൾ സൂക്ഷിക്കുക."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant സജീവമാണ്"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ക്രമീകരണത്തിൽ കുറിപ്പുകൾക്കുള്ള ഡിഫോൾട്ട് ആപ്പ് സജ്ജീകരിക്കുക"</string> <string name="install_app" msgid="5066668100199613936">"ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യൂ"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"മൈക്രോഫോണും ക്യാമറയും"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"അടുത്തിടെയുള്ള ആപ്പ് ഉപയോഗം"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"അടുത്തിടെയുള്ള ആക്സസ് കാണുക"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index da9d794b4250..9c7cf8ba932d 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Өөр төхөөрөмжөөс системийн хэлийг өөрчлөх хүсэлт тавьсан"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Хэл солих"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Одоогийн хэлээр байлгах"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi-г хуваалцах"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Энэ сүлжээн дээр wireless debugging-г зөвшөөрөх үү?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Сүлжээний нэр (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi хаяг (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Энэ сүлжээн дээр үргэлж зөвшөөрөх"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Хээ буруу байна"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Нууц үг буруу байна"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Хэт олон удаа буруу оруулсан байна.\n<xliff:g id="NUMBER">%d</xliff:g> секундийн дараа дахин оролдоно уу."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Яаралтай тусламж"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Дахин оролдоно уу. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>-с <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> оролдлого үлдлээ."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Таны өгөгдлийг устгах болно"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Та дараагийн оролдлогоор буруу хээ оруулбал энэ төхөөрөмжийн өгөгдлийг устгах болно."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Таныг хуваалцаж, бичиж эсвэл дамжуулж байх үед <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> нь таны дэлгэцэд харагдаж буй зүйл эсвэл төхөөрөмжид тань тоглуулсан аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн мэдээлэл, мессеж, зураг, аудио болон видео зэрэг зүйлд болгоомжтой хандаарай."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Таныг хуваалцаж, бичлэг хийж эсвэл апп дамжуулж байх үед <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> нь тухайн аппад харуулсан эсвэл тоглуулсан аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио болон видео зэрэг бусад зүйлд болгоомжтой хандаарай."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Эхлүүлэх"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> энэ сонголтыг идэвхгүй болгосон"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Дамжуулж эхлэх үү?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Таныг дамжуулж байх үед Android таны дэлгэцэд харагдаж буй эсвэл төхөөрөмжид тань тоглуулсан аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн мэдээлэл, мессеж, зураг, аудио болон видео зэрэг зүйлд болгоомжтой хандаарай."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Таныг апп дамжуулж байх үед Android тухайн аппад харуулсан эсвэл тоглуулсан аливаа зүйлд хандах эрхтэй. Тиймээс нууц үг, төлбөрийн мэдээлэл, мессеж, зураг, аудио болон видео зэрэг зүйлд болгоомжтой хандаарай."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Туслах анхаарлаа хандуулж байна"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Тохиргоонд тэмдэглэлийн өгөгдмөл апп тохируулна уу"</string> <string name="install_app" msgid="5066668100199613936">"Аппыг суулгах"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон болон камер"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Аппын саяхны ашиглалт"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Саяхны хандалтыг харах"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 5fcf947018ce..72c5cb63fb52 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"दुसऱ्या डिव्हाइसद्वारे सिस्टीमची भाषा बदलण्याची विनंती केली गेली"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा बदला"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"सध्याची भाषा ठेवा"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"वाय-फाय शेअर करा"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"या नेटवर्कवर वायरलेस डीबगिंग करण्यासाठी अनुमती द्यायची का?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"नेटवर्कचे नाव (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nवाय-फाय ॲड्रेस (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"या नेटवर्कवर नेहमी अनुमती द्या"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"चुकीचा पॅटर्न"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"चुकीचा पासवर्ड"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"बरेच चुकीचे प्रयत्न. \n <xliff:g id="NUMBER">%d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"आणीबाणी"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"पुन्हा प्रयत्न करा. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> पैकी <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> प्रयत्न."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"तुमचा डेटा हटवला जाईल"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"तुम्ही पुढील प्रयत्नात चुकीचा पॅटर्न एंटर केल्यास, या डिव्हाइसचा डेटा हटवला जाईल."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"तुम्ही शेअर, रेकॉर्ड किंवा कास्ट करत असताना, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला तुमच्या स्क्रीनवर दाखवलेल्या किंवा डिव्हाइसवर प्ले केलेल्या कोणत्याही गोष्टीचा अॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"तुम्ही एखादे अॅप शेअर, रेकॉर्ड किंवा कास्ट करत असताना, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ला त्या अॅपवर दाखवलेल्या किंवा प्ले केलेल्या कोणत्याही गोष्टीचा अॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"सुरुवात करा"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा पर्याय बंद केला आहे"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"कास्ट करणे सुरू करायचे आहे का?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"तुम्ही कास्ट करत असताना, Android ला तुमच्या स्क्रीनवर दाखवलेल्या किंवा डिव्हाइसवर प्ले केलेल्या कोणत्याही गोष्टीचा अॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"तुम्ही एखादे अॅप कास्ट करत असताना, Android ला त्या अॅपवर दाखवलेल्या किंवा प्ले केलेल्या कोणत्याही गोष्टीचा अॅक्सेस असतो. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant चे लक्ष हे आता अॅक्टिव्ह आहे"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिंग्ज मध्ये डीफॉल्ट टिपा अॅप सेट करा"</string> <string name="install_app" msgid="5066668100199613936">"अॅप इंस्टॉल करा"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"मायक्रोफोन आणि कॅमेरा"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"अलीकडील अॅप वापर"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"अलीकडील अॅक्सेस पहा"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index de88987c9609..fd4e6b51001c 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Permintaan pertukaran bahasa sistem oleh peranti lain"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Tukar bahasa"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Kekalkan bahasa semasa"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Kongsi Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Benarkan penyahpepijatan wayarles pada rangkaian ini?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nama Rangkaian (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAlamat Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Sentiasa benarkan pada rangkaian ini"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Corak salah"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Kata laluan salah"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Terlalu banyak percubaan yang salah.\nCuba lagi dalam masa <xliff:g id="NUMBER">%d</xliff:g> saat."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Kecemasan"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Cuba lagi. Percubaan <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> daripada <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Data anda akan dipadamkan"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Jika anda memasukkan corak yang salah pada percubaan seterusnya, data peranti ini akan dipadamkan."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Apabila anda membuat perkongsian, rakaman atau penghantaran, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> boleh mengakses apa-apa sahaja yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Apabila anda berkongsi, merakam atau menghantar apl, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> boleh mengakses apa-apa sahaja yang ditunjukan atau dimainkan pada apl tersebut. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Mula"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah melumpuhkan pilihan ini"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Mulakan penghantaran?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Apabila anda membuat penghantaran, Android boleh mengakses apa-apa sahaja yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Apabila anda menghantar apl, Android boleh mengakses apa-apa sahaja yang ditunjukan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Perhatian pembantu dihidupkan"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Tetapkan apl nota lalai dalam Tetapan"</string> <string name="install_app" msgid="5066668100199613936">"Pasang apl"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Paparkan pada paparan luaran?"</string> + <string name="enable_display" msgid="8308309634883321977">"Dayakan paparan"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon & Kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Penggunaan apl terbaharu"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Lihat akses terbaharu"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 1f54ef6c32a0..5d249dec93b0 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"စက်နောက်တစ်ခုက စနစ်၏ ဘာသာစကားပြောင်းရန် တောင်းဆိုထားသည်"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ဘာသာစကားပြောင်းရန်"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"လက်ရှိဘာသာစကားဆက်သုံးရန်"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi မျှဝေရန်"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ဤကွန်ရက်တွင် ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ခွင့်ပြုမလား။"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ကွန်ရက်အမည် (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi လိပ်စာ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ဤကွန်ရက်ကို အမြဲခွင့်ပြုပါ"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ပုံစံ မှားနေသည်"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"စကားဝှက် မှားနေသည်"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"မှားသည့် အကြိမ် အရေအတွက် အလွန်များသည်။\n<xliff:g id="NUMBER">%d</xliff:g>စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"အရေးပေါ်"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ထပ်စမ်းကြည့်ပါ။ <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> ကြိမ်အနက်မှ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ကြိမ် ဖြစ်သည်။"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"သင်၏ဒေတာများ ပျက်သွားပါလိမ့်မည်"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"မှားယွင်းသည့် ပုံစံကို နောက်တစ်ကြိမ်ထည့်သွင်းပါက ဤစက်ပစ္စည်းပေါ်ရှိ ဒေတာများကို ဖျက်လိုက်ပါမည်။"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"မျှဝေ၊ ရုပ်သံဖမ်း (သို့) ကာစ်လုပ်သည့်အခါ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် သင့်ဖန်သားပြင်ရှိ မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"အက်ပ်တစ်ခုဖြင့် မျှဝေ၊ ရုပ်သံဖမ်း (သို့) ကာစ်လုပ်သည့်အခါ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် ယင်းအက်ပ်တွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့အရာများကို ဂရုစိုက်ပါ။"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"စတင်ရန်"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ဤရွေးစရာကို ပိတ်ထားသည်"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ကာစ်လုပ်ခြင်း စမလား။"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ကာစ်လုပ်သည့်အခါ Android သည် သင့်ဖန်သားပြင်ရှိ မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"အက်ပ်တစ်ခုကို ကာစ်လုပ်သည့်အခါ Android သည် ယင်းအက်ပ်တွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant နားထောင်နေသည်"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ဆက်တင်များတွင် မူရင်းမှတ်စုများအက်ပ် သတ်မှတ်ပါ"</string> <string name="install_app" msgid="5066668100199613936">"အက်ပ် ထည့်သွင်းရန်"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"မိုက်ခရိုဖုန်းနှင့် ကင်မရာ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"လတ်တလော အက်ပ်အသုံးပြုမှု"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"လတ်တလောအသုံးပြုမှုကို ကြည့်ရန်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 54a5341fda2c..17846751a258 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Bytte av systemspråk er forespurt av en annen enhet"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Bytt språk"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Behold gjeldende språk"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Del wifi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vil du tillate trådløs feilsøking på dette nettverket?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nettverksnavn (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-adresse (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Tillat alltid på dette nettverket"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Feil mønster"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Feil passord"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"For mange ugyldige forsøk.\nPrøv på nytt om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Nødssituasjon"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Prøv på nytt. Forsøk <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> av <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Dataene dine blir slettet"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Hvis du oppgir feil mønster på neste forsøk, slettes dataene på denne enheten."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Når du deler, tar opp eller caster noe, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tilgang til alt som vises på skjermen eller spilles av på enheten. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Når du deler, tar opp eller caster en app, har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tilgang til alt som vises eller spilles av i den aktuelle appen. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Begynn"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktivert dette alternativet"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vil du begynne å caste?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Når du caster, har Android tilgang til alt som vises på skjermen eller spilles av på enheten. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Når du caster en app, har Android tilgang til alt som vises eller spilles av i den aktuelle appen. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistentoppmerksomhet er på"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Du kan velge en standardapp for notater i Innstillinger"</string> <string name="install_app" msgid="5066668100199613936">"Installer appen"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon og kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nylig appbruk"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se nylig tilgang"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 29b5098d0273..94ac4b7fcfc4 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"अर्को डिभाइसले सिस्टमको भाषा परिवर्तन गर्न अनुरोध गरेको छ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"भाषा परिवर्तन गर्नुहोस्"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"अहिलेको भाषा राख्नुहोस्"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi सेयर गर्नुहोस्"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"यस नेटवर्कमा वायरलेस डिबगिङ सेवा प्रयोग गर्न दिने हो?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"नेटवर्कको नाम (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi ठेगाना (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"यस नेटवर्कमा सधैँ अनुमति दिइयोस्"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"प्याटर्न मिलेन"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"पासवर्ड मिलेन"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"अत्यन्तै धेरै पटक गलत प्रयास गरिए। \n <xliff:g id="NUMBER">%d</xliff:g>सेकेन्ड पछि पुनः प्रयास गर्नुहोस्।"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"आपत्कालीन"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"फेरि प्रयास गर्नुहोस्। <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> मध्ये <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> प्रयास।"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"तपाईंको डेटा मेटाइने छ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"तपाईंले अर्को पटक पनि गलत ढाँचा प्रविष्टि गर्नुभयो भने यो डिभाइसको डेटा मेटाइने छ।"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"तपाईंले कुनै एप सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले उक्त एपमा देखाइने वा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"सुरु गर्नुहोस्"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले यो विकल्प अफ गर्नुभएको छ"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"कास्ट गर्न थाल्ने हो?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"तपाईंले कास्ट गर्दा Android ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"तपाईंले कुनै एप कास्ट गर्दा Android ले उक्त एपमा देखाइने वा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"सहायकले सुनिरहेको छ"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"सेटिङमा गई नोट बनाउने डिफल्ट एप तोक्नुहोस्"</string> <string name="install_app" msgid="5066668100199613936">"एप इन्स्टल गर्नुहोस्"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"माइक्रोफोन तथा क्यामेरा"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"एपको हालसालैको प्रयोग"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"हालसालै एक्सेस गर्ने एप हेर्नुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 5799c3516275..f15eda0eaec0 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Wijziging van systeemtaal aangevraagd door een ander apparaat"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Taal wijzigen"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Huidige taal houden"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wifi delen"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Draadloze foutopsporing toestaan in dit netwerk?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Netwerknaam (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWifi-adres (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Altijd toestaan in dit netwerk"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Onjuist patroon"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Onjuist wachtwoord"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Te veel onjuiste pogingen.\nProbeer het over <xliff:g id="NUMBER">%d</xliff:g> seconden opnieuw."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Noodgeval"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Probeer het opnieuw. Poging <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> van <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Je gegevens worden verwijderd"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Als je bij de volgende poging een onjuist patroon opgeeft, worden de gegevens van dit apparaat verwijderd."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Als je deelt, opneemt of cast, heeft <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Als je deelt, opneemt of cast, heeft <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Starten"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Voor <xliff:g id="APP_NAME">%1$s</xliff:g> staat deze optie uit"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Casten starten?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Als je cast, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Als je een app cast, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent-aandacht aan"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standaard notitie-app instellen in Instellingen"</string> <string name="install_app" msgid="5066668100199613936">"App installeren"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfoon en camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Recent app-gebruik"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Recente toegang bekijken"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 68acfc041a38..8e34628e67de 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ଅନ୍ୟ ଏକ ଡିଭାଇସ ଦ୍ୱାରା ସିଷ୍ଟମ ଭାଷା ପରିବର୍ତ୍ତନ ପାଇଁ ଅନୁରୋଧ କରାଯାଇଛି"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ଭାଷା ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ବର୍ତ୍ତମାନର ଭାଷା ରଖନ୍ତୁ"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ୱାଇ-ଫାଇ ସେୟାର କରନ୍ତୁ"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ଏହି ନେଟୱାର୍କରେ ୱାୟାରଲେସ୍ ଡିବଗିଂ ପାଇଁ ଅନୁମତି ଦେବେ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ନେଟୱାର୍କ ନାମ (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nୱାଇଫାଇ ଠିକଣା (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ସର୍ବଦା ଏହି ନେଟୱାର୍କରେ ଅନୁମତି ଦିଅନ୍ତୁ"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ଭୁଲ ପାଟର୍ନ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ଭୁଲ ପାସ୍ୱାର୍ଡ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ଅନେକ ଥର ଭୁଲ ଚେଷ୍ଟା। \n <xliff:g id="NUMBER">%d</xliff:g>ସେକେଣ୍ଡରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ଜରୁରୀକାଳୀନ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ। <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>ଟିରୁ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>ଟି ପ୍ରଚେଷ୍ଟା।"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ଆପଣଙ୍କ ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ଆପଣ ପରବର୍ତ୍ତୀ ପ୍ରଚେଷ୍ଟାରେ ଏକ ଭୁଲ ପାଟର୍ନ ପ୍ରବେଶ କଲେ, ଏହି ଡିଭାଇସର ଡାଟାକୁ ଡିଲିଟ୍ କରିଦିଆଯିବ।"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"ଆପଣ ସେୟାର, ରେକର୍ଡ କିମ୍ବା କାଷ୍ଟ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ଆପଣ ଏକ ଆପ ସେୟାର, ରେକର୍ଡ କିମ୍ବା କାଷ୍ଟ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ଆରମ୍ଭ କରନ୍ତୁ"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଏହି ବିକଳ୍ପକୁ ଅକ୍ଷମ କରିଛି"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"କାଷ୍ଟିଂ ଆରମ୍ଭ କରିବେ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ଆପଣ କାଷ୍ଟ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ଆପଣ ଏକ ଆପ କାଷ୍ଟ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ଆଟେନସନ ଚାଲୁ ଅଛି"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ସେଟିଂସରେ ଡିଫଲ୍ଟ ନୋଟ୍ସ ଆପ ସେଟ କରନ୍ତୁ"</string> <string name="install_app" msgid="5066668100199613936">"ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ମାଇକ୍ରୋଫୋନ ଏବଂ କେମେରା"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ବର୍ତ୍ତମାନର ଆପ ବ୍ୟବହାର"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ବର୍ତ୍ତମାନର ଆକ୍ସେସ ଦେଖନ୍ତୁ"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index f8aac7593697..0861ca3ac1be 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"ਕਿਸੇ ਹੋਰ ਡੀਵਾਈਸ ਵੱਲੋਂ ਸਿਸਟਮ ਦੀ ਭਾਸ਼ਾ ਬਦਲਣ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"ਭਾਸ਼ਾ ਬਦਲੋ"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ਮੌਜੂਦਾ ਭਾਸ਼ਾ ਰੱਖੋ"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"ਵਾਈ-ਫਾਈ ਸਾਂਝਾ ਕਰੋ"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ਕੀ ਇਸ ਨੈੱਟਵਰਕ \'ਤੇ ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ਨੈੱਟਵਰਕ ਨਾਮ (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nਵਾਈ-ਫਾਈ ਪਤਾ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ਇਸ ਨੈੱਟਵਰਕ \'ਤੇ ਹਮੇਸ਼ਾਂ ਆਗਿਆ ਦਿਓ"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ਗਲਤ ਪੈਟਰਨ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"ਗਲਤ ਪਾਸਵਰਡ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ਬਹੁਤ ਸਾਰੀਆਂ ਗ਼ਲਤ ਕੋਸ਼ਿਸ਼ਾਂ।\n<xliff:g id="NUMBER">%d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ਐਮਰਜੈਂਸੀ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ। <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ਕੋਸ਼ਿਸ਼।"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ਤੁਹਾਡਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ਜੇ ਤੁਸੀਂ ਅਗਲੀ ਕੋਸ਼ਿਸ਼ ਵਿੱਚ ਕੋਈ ਗਲਤ ਪੈਟਰਨ ਦਾਖਲ ਕਰਦੇ ਹੋ, ਤਾਂ ਇਸ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡਿੰਗ ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਣ ਵਾਲੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡ ਕਰਨ, ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ਸ਼ੁਰੂ ਕਰੋ"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੇ ਇਸ ਵਿਕਲਪ ਨੂੰ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ਕੀ ਕਾਸਟ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant ਧਿਆਨ ਸੁਵਿਧਾ ਨੂੰ ਚਾਲੂ ਹੈ"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਨੋਟ ਐਪ ਨੂੰ ਸੈੱਟ ਕਰੋ"</string> <string name="install_app" msgid="5066668100199613936">"ਐਪ ਸਥਾਪਤ ਕਰੋ"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਕੈਮਰਾ"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ਹਾਲ ਹੀ ਵਿੱਚ ਵਰਤੀ ਗਈ ਐਪ"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ਹਾਲੀਆ ਪਹੁੰਚ ਦੇਖੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index ad63d1ead9a9..fff57dba3b7c 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Inny użytkownik poprosił o zmianę języka systemu"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Zmień język"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Zachowaj bieżący język"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Udostępnij Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Zezwolić na debugowanie bezprzewodowe w tej sieci?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nazwa sieci (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdres Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Zawsze zezwalaj w tej sieci"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Nieprawidłowy wzór"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Nieprawidłowe hasło"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Zbyt wiele nieudanych prób.\n Spróbuj ponownie za <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Połączenie alarmowe"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Spróbuj ponownie. Próba <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> z <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Dane zostaną usunięte"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Jeśli następnym razem podasz nieprawidłowy wzór, dane na urządzeniu zostaną usunięte."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Rozpocznij"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Rozpocząć przesyłanie?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Podczas przesyłania, Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Podczas przesyłania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asystent jest aktywny"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ustaw domyślną aplikację do obsługi notatek w Ustawieniach"</string> <string name="install_app" msgid="5066668100199613936">"Zainstaluj aplikację"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon i aparat"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikacje korzystające w ostatnim czasie"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobacz ostatni dostęp"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 7f917c8d99f5..431863e62ecf 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mudança do idioma do sistema solicitada por outro dispositivo"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Manter idioma atual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Compartilhar Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Permitir a depuração por Wi-Fi nesta rede?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nome da rede (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nEndereço do Wi-Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Sempre permitir nesta rede"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Padrão incorreto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Senha incorreta"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Excesso de tentativas incorretas.\nTente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergência"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Tente novamente. Tentativa <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Seus dados serão excluídos"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Se você informar um padrão incorreto na próxima tentativa, os dados deste dispositivo serão excluídos."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quando você compartilha, grava ou transmite a tela, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quando você compartilha, grava ou transmite um app, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Início"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Começar a transmissão?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Quando você transmite a tela, o Android tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Quando você transmite um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string> <string name="install_app" msgid="5066668100199613936">"Instalar o app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index e455f01fb768..1c0ff6b1a105 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Alteração do idioma do sistema solicitada por outro dispositivo"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Manter idioma atual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Partilhar Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Permitir a depuração sem fios nesta rede?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nome da rede (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nEndereço Wi-Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permitir sempre nesta rede"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Padrão incorreto."</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Palavra-passe incorreta."</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Demasiadas tentativas incorretas.\nTente novamente dentro de <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergência"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Tente novamente. Tentativa <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Os seus dados serão eliminados"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Se introduzir um padrão incorreto na tentativa seguinte, os dados deste dispositivo serão eliminados."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quando está a partilhar, gravar ou transmitir, a app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a tudo o que está visível no seu ecrã ou é reproduzido no seu dispositivo. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quando está a partilhar, gravar ou transmitir uma app, a app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a tudo o que é apresentado ou reproduzido nessa app. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Iniciar"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou esta opção"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Começar a transmitir?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Quando está a transmitir conteúdo, o Android tem acesso a tudo o que está visível no seu ecrã ou é reproduzido no seu dispositivo. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Quando está a transmitir uma app, o Android tem acesso a tudo o que é apresentado ou reproduzido nessa app. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Predefina a app de notas nas Definições"</string> <string name="install_app" msgid="5066668100199613936">"Instalar app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Espelhar para o ecrã externo?"</string> + <string name="enable_display" msgid="8308309634883321977">"Ativar ecrã"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmara"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilização recente da app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ver acesso recente"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 7f917c8d99f5..431863e62ecf 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mudança do idioma do sistema solicitada por outro dispositivo"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Alterar idioma"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Manter idioma atual"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Compartilhar Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Permitir a depuração por Wi-Fi nesta rede?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nome da rede (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nEndereço do Wi-Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Sempre permitir nesta rede"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Padrão incorreto"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Senha incorreta"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Excesso de tentativas incorretas.\nTente novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergência"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Tente novamente. Tentativa <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> de <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Seus dados serão excluídos"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Se você informar um padrão incorreto na próxima tentativa, os dados deste dispositivo serão excluídos."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quando você compartilha, grava ou transmite a tela, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quando você compartilha, grava ou transmite um app, o <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tem acesso a todas as informações visíveis ou reproduzidas no dispositivo. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Início"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Começar a transmissão?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Quando você transmite a tela, o Android tem acesso a todas as informações visíveis nela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Quando você transmite um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Atenção do Assistente ativada"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Defina o app de notas padrão nas Configurações"</string> <string name="install_app" msgid="5066668100199613936">"Instalar o app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfone e câmera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Uso recente do app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Consultar acessos recentes"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 844027a4924d..513abc28a33d 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Alt dispozitiv solicită schimbarea limbii de sistem"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Schimbă limba"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Păstrează limba actuală"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Permite accesul la Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Permiți remedierea erorilor wireless în această rețea?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Numele rețelei (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Permite întotdeauna în această rețea"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Model greșit"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Parolă greșită"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Prea multe încercări incorecte.\nÎncearcă din nou peste <xliff:g id="NUMBER">%d</xliff:g> secunde."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Urgență"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Încearcă din nou. Încercarea <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> din <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Datele tale vor fi șterse"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Dacă la următoarea încercare introduci un model incorect, datele de pe acest dispozitiv vor fi șterse."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Când permiți accesul, înregistrezi sau proiectezi, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> are acces la orice este vizibil pe ecran sau se redă pe dispozitiv. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Când permiți accesul, înregistrezi sau proiectezi o aplicație, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> are acces la orice se afișează pe ecran sau se redă în aplicație. Prin urmare, ai grijă cu informații cum ar fi parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Începe"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a dezactivat această opțiune"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Începi să proiectezi?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Când proiectezi, Android are acces la orice este vizibil pe ecran sau se redă pe dispozitiv. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Când proiectezi o aplicație, Android are acces la orice se afișează sau se redă în aplicație. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistentul este atent"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setează aplicația prestabilită de note din Setări"</string> <string name="install_app" msgid="5066668100199613936">"Instalează aplicația"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Microfon și cameră"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilizare recentă în aplicații"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Vezi accesarea recentă"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 9728103a0e9a..694ccdf1aeb1 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Получен запрос на изменение системного языка от другого устройства."</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Изменить язык"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Оставить текущий язык"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Поделиться Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Разрешить отладку по Wi-Fi в этой сети?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Название сети (SSID):\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nMAC-адрес точки доступа (BSSID):\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Всегда разрешать отладку в этой сети"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Неверный графический ключ."</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Неверный пароль."</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Слишком много неудачных попыток.\nПовторите через <xliff:g id="NUMBER">%d</xliff:g> сек."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Экстренный вызов"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Попробуйте ещё раз. Попытка <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> из <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Осталась одна попытка"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Если вы неправильно введете графический ключ ещё раз, с устройства будут удалены все данные."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Когда вы демонстрируете, транслируете экран или записываете видео с него, приложение \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" получает доступ ко всему, что видно или воспроизводится на устройстве. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Когда вы демонстрируете, записываете или транслируете экран приложения, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> получает доступ ко всему, что видно или воспроизводится в этом приложении. Будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Начать"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" отключило эту возможность"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Начать трансляцию?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Во время трансляции система Android получает доступ ко всему, что видно или воспроизводится на устройстве. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Когда вы транслируете экран приложения, система Android получает доступ ко всему, что видно или воспроизводится в нем. Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ассистент готов слушать"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Задайте стандартное приложение для заметок в настройках."</string> <string name="install_app" msgid="5066668100199613936">"Установить приложение"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавнее использование приложениями"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Посмотреть недавний доступ"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 2424fe11f50a..7ac474d67c8f 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"වෙනත් උපාංගයකින් පද්ධති භාෂාව වෙනස් කිරීම ඉල්ලා ඇත"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"භාෂාව වෙනස් කරන්න"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"වත්මන් භාෂාව තබා ගන්න"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi බෙදා ගන්න"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"මෙම ජාලයේ නොරැහැන් නිදොස්කරණය ඉඩ දෙන්නද?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ජාල නම (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi ලිපිනය (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"මෙම ජාලයේ සැමවිට ඉඩ දෙන්න"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"වැරදි රටාවකි"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"වැරදි මුරපදයකි"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"වැරදි උත්සාහයන් ගණන වැඩියි. තත්පර \n තත්පර <xliff:g id="NUMBER">%d</xliff:g>කින් නැවත උත්සාහ කරන්න."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"හදිසි අවස්ථාව"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"නැවත උත්සාහ කරන්න. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>කින් <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> උත්සාහය."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ඔබේ දත්ත මකනු ඇත"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"ඔබ ඊළඟ උත්සාහයේදී වැරදි රටාවක් ඇතුළු කළහොත්, මෙම උපාංගයෙහි දත්ත මකනු ඇත."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"ඔබ බෙදා ගන්නා විට, පටිගත කරන විට, හෝ විකාශනය කරන විට, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> හට ඔබේ තිරයේ පෙනෙන හෝ ඔබේ උපාංගයේ වාදනය වන ඕනෑම දෙයකට ප්රවේශය ඇත. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ඔබ යෙදුමක් බෙදා ගන්නා විට, පටිගත කරන විට හෝ විකාශය කරන විට, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> හට එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයකට ප්රවේශය ඇත. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"අරඹන්න"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම විකල්පය අබල කර ඇත"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"විකාශය ආරම්භ කරන්න ද?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ඔබ විකාශය කරන විට, Android හට ඔබේ තිරයේ පෙනෙන හෝ ඔබේ උපාංගයේ වාදනය වන ඕනෑම දෙයකට ප්රවේශය ඇත. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ඔබ යෙදුමක් විකාශය කරන විට, Android හට එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයකට ප්රවේශය ඇත. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවුඩ, ඡායාරූප, සහ ශ්රව්ය සහ දෘශ්ය වැනි දේවල් පිළිබඳ ප්රවේශම් වන්න."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"සහයක අවධානය යොමු කරයි"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"සැකසීම් තුළ පෙරනිමි සටහන් යෙදුම සකසන්න"</string> <string name="install_app" msgid="5066668100199613936">"යෙදුම ස්ථාපනය කරන්න"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"මයික්රොෆෝනය සහ කැමරාව"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"මෑත යෙදුම් භාවිතය"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"මෑත ප්රවේශය බලන්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 4e1b46bf7660..92813d026370 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Zmenu jazyka systému vyžiadalo iné zariadenie"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Zmeniť jazyk"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Ponechať aktuálny jazyk"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Zdieľať Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Chcete povoliť bezdrôtové ladenie v tejto sieti?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Názov siete (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Vždy povoliť v tejto sieti"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Nesprávny vzor"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Nesprávne heslo"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Príliš veľa nesprávnych pokusov. \nSkúste to znova o <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Tieseň"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Skúste to znova. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. z <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> pokusov."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vaše dáta budú odstránené"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ak pri ďalšom pokuse zadáte nesprávny vzor, dáta tohto zariadenia budú odstránené."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Počas zdieľania, nahrávania alebo prenosu bude mať <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému, čo sa zobrazuje na obrazovke alebo prehráva v zariadení. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Počas zdieľania, nahrávania alebo prenosu v aplikácii bude mať <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému, čo sa v danej aplikácii zobrazuje alebo prehráva. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Začať"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> túto možnosť zakázala"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Chcete spustiť prenos?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Počas prenosu bude mať Android prístup k všetkému, čo sa zobrazuje na obrazovke alebo prehráva v zariadení. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Počas prenosu v aplikácii bude mať Android prístup k všetkému, čo sa v danej aplikácii zobrazuje alebo prehráva. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Pozornosť Asistenta je zapnutá"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavte predvolenú aplikáciu na poznámky v Nastaveniach"</string> <string name="install_app" msgid="5066668100199613936">"Inštalovať aplikáciu"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofón a fotoaparát"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedávne využitie aplikácie"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Zobraziť nedávny prístup"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 89e9276377ec..065035480574 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Spremembo jezika sistema je zahtevala druga naprava."</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Spremeni jezik"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Obdrži trenutni jezik"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Delite omrežje Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Ali dovolite brezžično odpravljanje napak v tem omrežju?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Ime omrežja (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nNaslov omrežja Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Vedno dovoli v tem omrežju"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Napačen vzorec"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Napačno geslo"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Preveč napačnih poskusov.\nPoskusite znova čez <xliff:g id="NUMBER">%d</xliff:g> s."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Nujni primer"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Poskusite znova. Poskus <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> od <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Vaši podatki bodo izbrisani"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Če pri naslednjem poskusu vnesete napačen vzorec, bodo podatki v tej napravi izbrisani."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Pri deljenju, snemanju ali predvajanju ima aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Pri deljenju, snemanju ali predvajanju aplikacije ima aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Začni"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite začeti predvajati?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Pri predvajanju ima Android dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Pri predvajanju aplikacije ima Android dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Zaznavanje pomočnika je vklopljeno."</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Nastavite privzeto aplikacijo za zapiske v nastavitvah."</string> <string name="install_app" msgid="5066668100199613936">"Namesti aplikacijo"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon in fotoaparat"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Nedavna uporaba v aplikacijah"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ogled nedavnih dostopov"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 2c61054b1074..08d3c55381da 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Një pajisje tjetër kërkoi ndryshimin e gjuhës së sistemit"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ndrysho gjuhën"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mbaj gjuhën aktuale"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Ndaj Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Të lejohet korrigjimi përmes Wi-Fi në këtë rrjet?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Emri i rrjetit (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Lejo gjithmonë në këtë rrjet"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Motiv i gabuar"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Fjalëkalim i gabuar"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Shumë tentativa të pasakta.\nProvo përsëri brenda <xliff:g id="NUMBER">%d</xliff:g> sekondash."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Urgjencë"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Provo sërish. Tentativa <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> nga <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Të dhënat e tua do të fshihen"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Nëse fut një motiv të pasaktë në tentativën tjetër, të dhënat e kësaj pajisjeje do të fshihen."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kur ti ndan, regjistron ose transmeton, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në pajisjen tënde. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kur ti ndan, regjistron ose transmeton një aplikacion, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në atë aplikacion. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Nis"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> e ka çaktivizuar këtë opsion"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Të niset transmetimi?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kur ti transmeton, Android ka qasje te çdo gjë e dukshme në ekranin tënd ose që po luhet në pajisjen tënde. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kur ti transmeton një aplikacion, Android ka qasje te çdo gjë e dukshme ose që po luhet në atë aplikacion. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesës, mesazhet, fotografitë, si dhe audion dhe videon."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Vëmendja e \"Asistentit\" aktive"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Cakto aplikacionin e parazgjedhur të shënimeve te \"Cilësimet\""</string> <string name="install_app" msgid="5066668100199613936">"Instalo aplikacionin"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofoni dhe kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Përdorimi i fundit i aplikacionit"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Shiko qasjen e fundit"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 7b2082900690..1856303313f5 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Други уређај је затражио промену језика система"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Промени језик"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Задржи актуелни језик"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Дели WiFi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Желите да дозволите бежично отклањање грешака на овој мрежи?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Назив мреже (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi адреса (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Увек дозволи на овој мрежи"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Погрешан шаблон"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Погрешна лозинка"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Превише нетачних покушаја.\n Пробајте поново за <xliff:g id="NUMBER">%d</xliff:g> сек."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Хитан случај"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Пробајте поново. <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>. покушај од <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Подаци ће се избрисати"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ако унесете нетачан шаблон при следећем покушају, избрисаћемо податке са овог уређаја."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Када делите, снимате или пребацујете, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видео снимцима."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видео снимцима."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Покрени"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућила ову опцију"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Желите да започнете пребацивање?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Када пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видео снимцима."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Када пребацујете апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видео снимцима."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Помоћник је у активном стању"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Подесите подразумевану апликацију за белешке у Подешавањима"</string> <string name="install_app" msgid="5066668100199613936">"Инсталирај апликацију"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Микрофон и камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Недавно користила апликација"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Прикажи недавни приступ"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 0ebb7784d4a5..76b6f1db9e45 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ändring av systemspråk har begärts av en annan enhet"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Ändra språk"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Behåll nuvarande språk"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Dela wifi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vill du tillåta trådlös felsökning i det här nätverket?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Nätverksnamn (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi-adress (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Tillåt alltid i det här nätverket"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Fel mönster"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Fel lösenord"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"För många felaktiga försök.\nFörsök igen om <xliff:g id="NUMBER">%d</xliff:g> sekunder."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Nödsituation"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Försök igen. Försök <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> av <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Din data raderas."</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Enhetens data raderas om du ritar fel mönster vid nästa försök."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"När du delar, spelar in eller castar har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> åtkomst till allt som visas på skärmen eller spelas upp på enheten. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton och ljud och video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"När du delar, spelar in eller castar en app har <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> åtkomst till allt som visas eller spelas upp i appen. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton och ljud och video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Börja"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inaktiverat alternativet"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vill du börja casta?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"När du castar har Android åtkomst till allt som visas på skärmen eller spelas upp på enheten. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton och ljud och video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"När du castar en app har Android åtkomst till allt som visas eller spelas upp i appen. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton och ljud och video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistenten är aktiverad"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ställ in en standardapp för anteckningar i inställningarna"</string> <string name="install_app" msgid="5066668100199613936">"Installera appen"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon och kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Senaste appanvändning"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Se senaste åtkomst"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 29d64052bc9c..17135446878f 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Mabadiliko ya lugha ya mfumo yameombwa na kifaa kingine"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Badilisha lugha"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Usibadilishe lugha ya sasa"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Shiriki Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Ungependa kuruhusu utatuzi usiotumia waya kwenye mtandao huu?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Jina la Mtandao (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAnwani ya Wi-Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Ruhusu kila wakati kwenye mtandao huu"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Mchoro si sahihi"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Nenosiri si sahihi"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Majaribio mengi mno yasiyo sahihi.\nJaribu tena baada ya sekunde <xliff:g id="NUMBER">%d</xliff:g>."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Simu za dharura"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Jaribu tena. Jaribio la <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> kati ya <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Data yako itafutwa"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Ukiweka mchoro usio sahihi utakapojaribu tena, data iliyo kwenye kifaa hiki itafutwa."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Unaposhiriki, kurekodi au kutuma, programu ya <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Unaposhiriki, kurekodi au kutuma programu, programu, programu ya <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Anza"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezima chaguo hili"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Ungependa kuanza kutuma?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Unapotuma, Android inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Unapotuma programu, Android inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Programu ya Mratibu imewashwa"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Teua programu chaguomsingi ya madokezo katika Mipangilio"</string> <string name="install_app" msgid="5066668100199613936">"Sakinisha programu"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Maikrofoni na Kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Matumizi ya programu hivi majuzi"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Angalia ufikiaji wa majuzi"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 13e92e5cfcfd..c0e4c3d716ee 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"சிஸ்டம் மொழியை மாற்றும்படி வேறொரு சாதனம் கோருகிறது"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"மொழியை மாற்று"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"தற்போதைய மொழியை வைத்திரு"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"வைஃபையைப் பகிர்"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"இந்த நெட்வொர்க்கில் வைஃபை பிழைதிருத்தத்தை அனுமதிக்கவா?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"நெட்வொர்க் பெயர் (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nவைஃபை முகவரி (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"இந்த நெட்வொர்க்கில் எப்போதும் அனுமதி"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"தவறான பேட்டர்ன்"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"தவறான கடவுச்சொல்"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"பல தவறான முயற்சிகள்.\n<xliff:g id="NUMBER">%d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"அவசர அழைப்பு"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"மீண்டும் முயலவும். <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> முறை முயன்றுவிட்டீர்கள்."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"உங்கள் தரவு நீக்கப்படும்"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"அடுத்த முறை தவறான பேட்டர்னை வரைந்தால் இந்தச் சாதனத்தின் தரவு நீக்கப்படும்."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"நீங்கள் பகிரும்போதோ ரெக்கார்டு செய்யும்போதோ அலைபரப்பும்போதோ உங்கள் திரையில் காட்டப்படுகின்ற அல்லது சாதனத்தில் பிளே செய்யப்படுகின்ற அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ஆப்ஸால் அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"நீங்கள் ஓர் ஆப்ஸைப் பகிரும்போதோ ரெக்கார்டு செய்யும்போதோ அலைபரப்பும்போதோ அந்த ஆப்ஸில் காட்டப்படுகின்ற அல்லது பிளே செய்யப்படுகின்ற அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ஆப்ஸால் அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"தொடங்கு"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இந்த விருப்பத்தை முடக்கியுள்ளது"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"அலைபரப்பைத் தொடங்கவா?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"நீங்கள் அலைபரப்பும்போது உங்கள் திரையில் காட்டப்படுகின்ற அல்லது சாதனத்தில் பிளே செய்யப்படுகின்ற அனைத்தையும் Android அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ஓர் ஆப்ஸை நீங்கள் அலைபரப்பும்போது அந்த ஆப்ஸில் காட்டப்படுகின்ற அல்லது பிளே செய்யப்படுகின்ற அனைத்தையும் Android அணுக முடியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"அசிஸ்டண்ட்டின் கவனம் இயக்கத்தில் உள்ளது"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"குறிப்பு எடுப்பதற்கான இயல்புநிலை ஆப்ஸை அமைப்புகளில் அமையுங்கள்"</string> <string name="install_app" msgid="5066668100199613936">"ஆப்ஸை நிறுவுங்கள்"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"மைக்ரோஃபோனும் கேமராவும்"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"சமீபத்திய ஆப்ஸ் பயன்பாடு"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"சமீபத்திய அணுகலைக் காட்டு"</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 421fec66424f..22a329b4e648 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"మరొక పరికరం ద్వారా సిస్టమ్ భాష మార్పు రిక్వెస్ట్ చేయబడింది"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"భాషను మార్చండి"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ప్రస్తుత భాషను అలా ఉంచండి"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi షేర్ చేయండి"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్వర్క్ ద్వారా వైర్లెస్ డీబగ్గింగ్ను అనుమతించాలా?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్వర్క్ నుండి ఎల్లప్పుడూ అనుమతించండి"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"ఆకృతి తప్పు"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"పాస్వర్డ్ తప్పు"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు.\n<xliff:g id="NUMBER">%d</xliff:g> సెకన్ల తర్వాత మళ్లీ ట్రై చేయండి."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ఎమర్జెన్సీ"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"మళ్లీ ట్రై చేయండి. <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>లో <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> ప్రయత్నం చేశారు."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"మీ డేటా తొలగించబడుతుంది"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"మీరు ఒకవేళ తర్వాతి ప్రయత్నంలో తప్పు ఆకృతిని ఎంటర్ చేస్తే, ఈ పరికరం యొక్క డేటా తొలగించబడుతుంది."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"మీరు షేర్ చేస్తున్నప్పుడు, రికార్డ్ చేస్తున్నప్పుడు, లేదా ప్రసారం చేస్తున్నప్పుడు, మీ స్క్రీన్పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>కు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"మీరు ఏదైనా యాప్ను షేర్ చేస్తున్నప్పుడు, రికార్డ్ చేస్తున్నప్పుడు, లేదా ప్రసారం చేస్తున్నప్పుడు, ఆ యాప్లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>కు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ప్రారంభించండి"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ఈ ఆప్షన్ను డిజేబుల్ చేసింది"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ప్రసారాన్ని ప్రారంభించాలా?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"మీరు ప్రసారం చేసేటప్పుడు, మీ స్క్రీన్పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"మీరు ఏదైనా యాప్ను ప్రసారం చేసేటప్పుడు, ఆ యాప్లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్వర్డ్లు, పేమెంట్ వివరాలు, మెసేజ్లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistant అటెన్షన్ ఆన్లో ఉంది"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"సెట్టింగ్లలో ఆటోమేటిక్గా ఉండేలా ఒక నోట్స్ యాప్ను సెట్ చేసుకోండి"</string> <string name="install_app" msgid="5066668100199613936">"యాప్ను ఇన్స్టాల్ చేయండి"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"మైక్రోఫోన్ & కెమెరా"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"ఇటీవలి యాప్ వినియోగం"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ఇటీవలి యాక్సెస్ను చూడండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 05908069f0a2..3887b9f8b9c4 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"คำขอเปลี่ยนภาษาของระบบโดยอุปกรณ์อื่น"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"เปลี่ยนภาษา"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"ใช้ภาษาปัจจุบันต่อไป"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"แชร์ Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"อนุญาตให้แก้ไขข้อบกพร่องผ่าน Wi-Fi ในเครือข่ายนี้ใช่ไหม"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"ชื่อเครือข่าย (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nที่อยู่ Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"อนุญาตเสมอในเครือข่ายนี้"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"รูปแบบไม่ถูกต้อง"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"รหัสผ่านไม่ถูกต้อง"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"ดำเนินการไม่ถูกต้องหลายครั้งเกินไป\nลองอีกครั้งใน <xliff:g id="NUMBER">%d</xliff:g> วินาที"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ฉุกเฉิน"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"ลองอีกครั้ง ความพยายามครั้งที่ <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> จาก <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"ระบบจะลบข้อมูลของคุณ"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"หากคุณป้อนรูปแบบไม่ถูกต้องในความพยายามครั้งถัดไป ระบบจะลบข้อมูลในอุปกรณ์เครื่องนี้"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"เมื่อกำลังแชร์ บันทึก หรือแคสต์ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะมีสิทธิ์เข้าถึงทุกสิ่งที่ปรากฏบนหน้าจอหรือเล่นอยู่ในอุปกรณ์ ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"เมื่อกำลังแชร์ บันทึก หรือแคสต์แอป <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะมีสิทธิ์เข้าถึงทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"เริ่ม"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ปิดใช้ตัวเลือกนี้"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"เริ่มแคสต์เลยไหม"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"เมื่อกำลังแคสต์ Android จะมีสิทธิ์เข้าถึงทุกสิ่งที่ปรากฏบนหน้าจอหรือเล่นอยู่ในอุปกรณ์ ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"เมื่อกำลังแคสต์แอป Android จะมีสิทธิ์เข้าถึงทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"การเรียกใช้งาน Assistant เปิดอยู่"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"กำหนดแอปการจดบันทึกเริ่มต้นในการตั้งค่า"</string> <string name="install_app" msgid="5066668100199613936">"ติดตั้งแอป"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"ไมโครโฟนและกล้อง"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"การใช้แอปครั้งล่าสุด"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"ดูการเข้าถึงล่าสุด"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 859191a1fba9..2fdee7220e6c 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Hiniling ng ibang device na palitan ang wika ng system"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Palitan ang wika"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Huwag palitan ang wika"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Ibahagi ang Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Payagan ang wireless na pag-debug sa network na ito?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Pangalan ng Network (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAddress ng Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Palaging payagan sa network na ito"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Maling pattern"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Maling password"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Masyadong maraming maling pagsubok.\nSubukan ulit sa loob ng <xliff:g id="NUMBER">%d</xliff:g> (na) segundo."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Emergency"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Subukan ulit. ika-<xliff:g id="ATTEMPTS_0">%1$d</xliff:g> (na) pagsubok sa <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Made-delete ang iyong data"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Kung maling pattern ang mailalagay mo sa susunod na pagsubok, made-delete ang data ng device na ito."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kapag nagbabahagi, nagre-record, o nagka-cast ka, may access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa kahit anong nakikita sa iyong screen o pine-play sa device mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kapag nagbabahagi, nagre-record, o nagka-cast ka ng app, may access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Simulan"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Na-disable ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang opsyong ito"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Simulan ang pag-cast?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kapag nagka-cast ka, may access ang Android sa kahit anong nakikita sa iyong screen o pine-play sa device mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kapag nagka-cast ka ng app, may access ang Android sa kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string> @@ -1173,6 +1170,8 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Naka-on ang atensyon ng Assistant"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Magtakda ng default na app sa pagtatala sa Mga Setting"</string> <string name="install_app" msgid="5066668100199613936">"I-install ang app"</string> + <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"I-mirror sa external na display?"</string> + <string name="enable_display" msgid="8308309634883321977">"I-enable ang display"</string> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikropono at Camera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Kamakailang paggamit ng app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Tingnan ang kamakailang access"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index f217f131fd73..b01fee15ec5a 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Başka bir cihaz tarafından sistem dilinin değiştirilmesi istendi"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Dili değiştir"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mevcut dili koru"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Kablosuz ağı paylaşın"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Bu ağda kablosuz hata ayıklamaya izin verilsin mi?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Ağ Adı (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nKablosuz Adresi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Bu ağda her zaman izin ver"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Yanlış desen"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Yanlış şifre"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Çok fazla yanlış giriş yapıldı.\n<xliff:g id="NUMBER">%d</xliff:g> saniye içinde tekrar deneyin."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Acil durum"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Tekrar deneyin. Deneme sayısı: <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Verileriniz silinecek"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Bir sonraki denemenizde yanlış desen girerseniz bu cihazın verileri silinir."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Paylaşma, kaydetme ve yayınlama özelliklerini kullandığınızda <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ekranınızda görünen veya cihazınızda oynatılan her şeye erişebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Bir uygulamayı paylaştığınızda, kaydettiğinizde veya yayınladığınızda <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, söz konusu uygulamada gösterilen veya oynatılan her şeye erişebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Başlat"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçeneği devre dışı bıraktı"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Yayın başlatılsın mı?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Yayınlama özelliğini kullandığınızda Android, ekranınızda görünen veya cihazınızda oynatılan her şeye erişebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Bir uygulamayı yayınladığınızda Android, söz konusu uygulamada gösterilen veya oynatılan her şeye erişebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Asistan dinliyor"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Ayarlar\'ı kullanarak varsayılan notlar ayarlayın"</string> <string name="install_app" msgid="5066668100199613936">"Uygulamayı yükle"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon ve Kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Son uygulama kullanımı"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Son erişimi göster"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 83bfd6382c72..db3441352422 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Запит на змінення мови системи надіслано з іншого пристрою"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Змінити мову"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Залишити поточну мову"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Поділитися Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Дозволити налагодження через Wi-Fi у цій мережі?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Ім\'я мережі (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nАдреса Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Завжди дозволяти в цій мережі"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Неправильний ключ"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Неправильний пароль"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Забагато невдалих спроб.\nПовторіть за <xliff:g id="NUMBER">%d</xliff:g> с."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Екстрений виклик"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Спробуйте ще. Спроба <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> із <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Ваші дані буде видалено"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Якщо наступного разу ви введете неправильний ключ, дані на цьому пристрої буде видалено."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Коли ви показуєте, записуєте або транслюєте екран, додаток <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> отримує доступ до всього, що відображається на екрані чи відтворюється на пристрої. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Коли ви показуєте, записуєте або транслюєте додаток, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> отримує доступ до всього, що відображається або відтворюється в цьому додатку. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Почати"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> вимкнув цю опцію"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Почати трансляцію?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Під час трансляції ОС Android отримує доступ до всього, що відображається на екрані чи відтворюється на пристрої. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Коли ви транслюєте додаток, ОС Android отримує доступ до всього, що відображається або відтворюється в ньому. Тому будьте уважні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Асистента активовано"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Призначте стандартний додаток для нотаток у налаштуваннях"</string> <string name="install_app" msgid="5066668100199613936">"Установити додаток"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Мікрофон і камера"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Нещодавнє використання додатками"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Переглянути нещодавній доступ"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index eac34ce72266..8115e2e086ca 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"کسی دوسرے آلے کے ذریعے سسٹم کی زبان میں تبدیلی کی درخواست کی گئی"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"زبان تبدیل کریں"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"موجودہ زبان برقرار رکھیں"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi-Fi کا اشتراک کریں"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"اس نیٹ ورک پر وائرلیس ڈیبگنگ کرنے کی اجازت دیں؟"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"نیٹ ورک کا نام (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\n Wi-Fi کا پتہ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"اس نیٹ ورک پر ہمیشہ اجازت دیں"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"غلط پیٹرن"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"غلط پاس ورڈ"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"کافی زیادہ غلط کوششیں کی گئیں۔\n <xliff:g id="NUMBER">%d</xliff:g> سیکنڈ بعد دوبارہ کوشش کریں۔"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"ایمرجنسی"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"دوبارہ کوشش کریں۔ کوشش <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> از <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>۔"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"آپ کا ڈیٹا حذف کر دیا جائے گا"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"اگر آپ نے اگلی کوشش میں غلط پیٹرن درج کیا تو اس آلے کا ڈیٹا حذف کر دیا جائے گا۔"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"جب آپ اشتراک، ریکارڈنگ یا کاسٹ کر رہے ہوتے ہیں تو <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کو آپ کی اسکرین پر دکھائی دینے والی یا آپ کے آلے پر چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"جب آپ اشتراک، ریکارڈنگ یا کسی ایپ کو کاسٹ کر رہے ہوتے ہیں تو <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کو اس ایپ پر دکھائی گئی یا چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"شروع کریں"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> نے اس اختیار کو غیر فعال کر دیا ہے"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"کاسٹ کرنا شروع کریں؟"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"جب آپ کاسٹ کر رہے ہوتے ہیں، تو Android کو آپ کی اسکرین پر دکھائی دینے والی یا آپ کے آلے پر چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"جب آپ کسی ایپ کو کاسٹ کر رہے ہوتے ہیں تو Android کو اس ایپ پر دکھائی گئی یا چلائی گئی ہر چیز تک رسائی حاصل ہوتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"اسسٹنٹ کی توجہ آن ہے"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"ترتیبات میں ڈیفالٹ نوٹس ایپ سیٹ کریں"</string> <string name="install_app" msgid="5066668100199613936">"ایپ انسٹال کریں"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"مائیکروفون اور کیمرا"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"حالیہ ایپ کا استعمال"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"حالیہ رسائی دیکھیں"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index 66c874d28dc4..30e0618c1563 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Tizim tilini oʻzgartirishni boshqa qurilma soʻragan"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Tilni almashtirish"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Joriy tilni qoldirish"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Wi‑Fi ulashuv"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Wi-Fi orqali debagging uchun ruxsat berilsinmi?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Tarmoq nomi (SSID):\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi Manzil (BSSID):\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Bu tarmoqda doim ruxsat etilsin"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Grafik kalit xato"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Parol xato"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Xato urinishlar soni oshib ketdi! \n <xliff:g id="NUMBER">%d</xliff:g> soniyadan keyin qayta urining."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Favqulodda holat"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Qaytadan urining. Urinish: <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> / <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Bitta urinish qoldi"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Agar grafik kalitni xato kiritsangiz, bu qurilmadagi maʼlumotlar oʻchirib tashlanadi."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Ulashish, yozib olish va translatsiya qilish vaqtida <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilovasi ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Ulashish, yozib olish va translatsiya qilish vaqtida <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilovasi ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Boshlash"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu sozlamani faolsizlantirgan"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Translatsiya boshlansinmi?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Translatsiya qilayotganingizda Android ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Translatsiya qilayotganingizda Android ekranda chiqadigan yoki qurilmada ijro qilinadigan kontentni koʻra oladi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Assistent diqqati yoniq"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Standart qaydlar ilovasini Sozlamalar orqali tanlang"</string> <string name="install_app" msgid="5066668100199613936">"Ilovani oʻrnatish"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofon va kamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Ilovadan oxirgi foydalanish"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Oxirgi ruxsatni koʻrish"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 2648d786ed72..f4c62a5297fe 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Thiết bị khác yêu cầu thay đổi ngôn ngữ hệ thống"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Thay đổi ngôn ngữ"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Giữ ngôn ngữ hiện tại"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Chia sẻ Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Cho phép gỡ lỗi qua Wi-Fi trên mạng này?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Tên mạng (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nĐịa chỉ Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Luôn cho phép trên mạng này"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Hình mở khóa không chính xác"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Mật khẩu sai"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Bạn đã nhập sai quá nhiều lần.\nHãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Khẩn cấp"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Thử lại. Lần thử <xliff:g id="ATTEMPTS_0">%1$d</xliff:g>/<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Dữ liệu của bạn sẽ bị xóa"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Nếu bạn nhập hình mở khóa không chính xác vào lần thử tiếp theo, thì dữ liệu trên thiết bị này sẽ bị xóa."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Khi bạn chia sẻ, ghi hoặc truyền, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào mọi nội dung xuất hiện trên màn hình hoặc phát trên thiết bị của bạn. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Khi bạn chia sẻ, ghi hoặc truyền ứng dụng, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ các thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Bắt đầu"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> đã tắt lựa chọn này"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Bắt đầu truyền?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Khi bạn truyền, Android sẽ có quyền truy cập vào mọi nội dung xuất hiện trên màn hình hoặc phát trên thiết bị của bạn. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Khi bạn truyền một ứng dụng, Android sẽ có quyền truy cập vào mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ các thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Trợ lý đang bật"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Đặt ứng dụng ghi chú mặc định trong phần Cài đặt"</string> <string name="install_app" msgid="5066668100199613936">"Cài đặt ứng dụng"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Micrô và máy ảnh"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Hoạt động sử dụng gần đây của ứng dụng"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Xem hoạt động truy cập gần đây"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 3072fa494bc7..f3ade0390797 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一台设备请求更改系统语言"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"更改语言"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"保持当前语言"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"分享 WLAN"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"要允许通过此网络进行无线调试吗?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"网络名称 (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWLAN 地址 (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"始终允许通过此网络进行调试"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"图案错误"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"密码错误"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"输错次数过多。\n请在 <xliff:g id="NUMBER">%d</xliff:g> 秒后重试。"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"紧急呼叫"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"请重试。您目前已尝试 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可尝试 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"您的数据将会被删除"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果您下次绘制的解锁图案仍然有误,此设备上的数据将会被删除。"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"在分享、录制或投放内容时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>可以访问屏幕上显示或设备中播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"在分享、录制或投放内容时,<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>可以访问通过此应用显示或播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"开始"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已停用此选项"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"开始投放?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"在投放内容时,Android 可以访问屏幕上显示或设备中播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"在投放某个应用时,Android 可以访问此应用显示或播放的所有内容。因此,请务必小心操作,谨防密码、付款信息、消息、照片、音频和视频等内容遭到泄露。"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"已开启 Google 助理感知功能"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在设置中设置默认记事应用"</string> <string name="install_app" msgid="5066668100199613936">"安装应用"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"麦克风和摄像头"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"近期应用对手机传感器的使用情况"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期使用情况"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 8f4adc05069e..efc567107d8f 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一部裝置要求變更系統語言"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"變更語言"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"保留目前語言"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"分享 Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"要在此網絡上允許無線偵錯功能嗎?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"網絡名稱 (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi 地址 (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"一律允許在此網絡上執行"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"圖案錯誤"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"密碼錯誤"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"輸入錯誤的次數太多,\n請於 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試。"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"緊急"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"請再試一次。你已嘗試 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可試 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"你的資料將會刪除"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果你下次畫出錯誤的上鎖圖案,系統將會刪除此裝置上的資料。"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"當你分享、錄影或投放時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"當你分享、錄影或投放應用程式時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取顯示在該應用程式中顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"開始"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"要開始投放嗎?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"當你投放時,Android 可存取顯示在螢幕畫面上或在裝置上播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"當你投放應用程式時,Android 可存取在該應用程式中顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"「Google 助理」感應功能已開啟"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設筆記應用程式"</string> <string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"近期應用程式使用情況"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 35b7231bd23b..af84a3122289 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"另一部裝置要求變更系統語言"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"變更語言"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"繼續使用目前的語言"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"分享 Wi-Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"要允許透過這個網路執行無線偵錯嗎?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"網路名稱 (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi 位址 (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"一律允許透過這個網路執行"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"圖案錯誤"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"密碼錯誤"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"錯誤次數過多,\n請於 <xliff:g id="NUMBER">%d</xliff:g> 秒後再試。"</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"緊急"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"請再試一次。你目前已嘗試 <xliff:g id="ATTEMPTS_0">%1$d</xliff:g> 次,最多可試 <xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g> 次。"</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"你的資料將遭到刪除"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"如果下次輸入的解鎖圖案仍不正確,系統將刪除這部裝置中的資料。"</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"當你分享、錄製或投放內容時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"當你分享、錄製或投放應用程式內容時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取應用程式中顯示的任何資訊或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"開始"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"要開始投放嗎?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"當你投放內容時,Android 可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"當你投放應用程式內容時,Android 可存取應用程式中顯示的任何資訊或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Google 助理感知功能已開啟"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"在「設定」中指定預設記事應用程式"</string> <string name="install_app" msgid="5066668100199613936">"安裝應用程式"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"麥克風和相機"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"最近曾使用感應器的應用程式"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"查看近期存取記錄"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 19c00e612b1c..11cf44b4e2e6 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -57,8 +57,7 @@ <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Ushintsho lolimi lwesistimu lucelwe enye idivayisi"</string> <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Shintsha ulimi"</string> <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Gcina ulimi lwamanje"</string> - <!-- no translation found for share_wifi_button_text (1285273973812029240) --> - <skip /> + <string name="share_wifi_button_text" msgid="1285273973812029240">"Yaba i-Wi‑Fi"</string> <string name="wifi_debugging_title" msgid="7300007687492186076">"Vumela ukulungisa amaphutha okungenantambo kule nethiwekhi?"</string> <string name="wifi_debugging_message" msgid="5461204211731802995">"Igama Lenethiwekhi (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nIkheli le-Wi‑Fi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string> <string name="wifi_debugging_always" msgid="2968383799517975155">"Njalo nje vumela le nethiwekhi"</string> @@ -160,8 +159,7 @@ <string name="biometric_dialog_wrong_pattern" msgid="8954812279840889029">"Iphethini engalungile"</string> <string name="biometric_dialog_wrong_password" msgid="69477929306843790">"Iphasiwedi engalungile"</string> <string name="biometric_dialog_credential_too_many_attempts" msgid="3083141271737748716">"Imizamo eminingi kakhulu engalungile.\nZama futhi kumasekhondi angu-<xliff:g id="NUMBER">%d</xliff:g>."</string> - <!-- no translation found for work_challenge_emergency_button_text (8946588434515599288) --> - <skip /> + <string name="work_challenge_emergency_button_text" msgid="8946588434515599288">"Isimo esiphuthumayo"</string> <string name="biometric_dialog_credential_attempts_before_wipe" msgid="6751859711975516999">"Zama futhi. Umzamo ongu-<xliff:g id="ATTEMPTS_0">%1$d</xliff:g> kwengu-<xliff:g id="MAX_ATTEMPTS">%2$d</xliff:g>."</string> <string name="biometric_dialog_last_attempt_before_wipe_dialog_title" msgid="2874250099278693477">"Idatha yakho izosuswa"</string> <string name="biometric_dialog_last_pattern_attempt_before_wipe_device" msgid="6562299244825817598">"Uma ufaka iphethini engalungile kumzamo olandelayo, idatha yale divayisi izosuswa."</string> @@ -415,8 +413,7 @@ <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Uma wabelana, urekhoda, noma usakaza, i-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inokufinyelela kunoma yini ebonakalayo kusikrini sakho noma edlalwa kudivayisi yakho. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yokukhokha, imilayezo, izithombe, nomsindo nevidiyo."</string> <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Uma wabelana, ukurekhoda, noma ukusakaza ku-app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inokufinyelela kunoma yini eboniswayo noma edlalwa kuleyo app. Ngakho-ke qaphela ngezinto ezfana namaphasiwedi, imininingwane yokukhokha, imilayezo, izithombe, nomsindo nevidiyo."</string> <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Qala"</string> - <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_disabled (8999903044874669995) --> - <skip /> + <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ivale le nketho"</string> <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Qala ukusakaza?"</string> <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Uma usakaza, i-Android inokufinyelela kunoma yini ebonakalayo kusikrini sakho noma edlalwa kudivayisi yakho. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yokukhokha, imilayezo, izithombe, nomsindo nevidiyo."</string> <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Uma usakaza i-app, i-Android inokufinyelela kunoma yini eboniswayo noma edlalwa kuleyo app. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string> @@ -1173,6 +1170,10 @@ <string name="assistant_attention_content_description" msgid="6830215897604642875">"Ukunaka kwe-Assistant kuvuliwe"</string> <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Setha i-app yamanothi azenzakalelayo Kumsethingi"</string> <string name="install_app" msgid="5066668100199613936">"Faka i-app"</string> + <!-- no translation found for connected_display_dialog_start_mirroring (6237895789920854982) --> + <skip /> + <!-- no translation found for enable_display (8308309634883321977) --> + <skip /> <string name="privacy_dialog_title" msgid="7839968133469098311">"Imakrofoni Nekhamera"</string> <string name="privacy_dialog_summary" msgid="2458769652125995409">"Ukusetshenziswa kwakamuva kwe-app"</string> <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Bona ukufinyelela kwakamuva"</string> diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java index 56c0953cd822..5f33ef91ed9c 100644 --- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java +++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java @@ -61,7 +61,7 @@ public class PinShapeNonHintingView extends LinearLayout implements PinShapeInpu @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); - if (getChildCount() > 0) { + if (getChildCount() > 2) { View firstChild = getChildAt(0); boolean isVisible = firstChild.getLocalVisibleRect(mFirstChildVisibleRect); boolean clipped = mFirstChildVisibleRect.left > 0 diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java index 8dbe5e00ab7e..d59f51ffe030 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java @@ -24,7 +24,7 @@ import java.lang.annotation.Retention; import javax.inject.Scope; /** - * Scope annotation for singleton items within the CentralSurfacesComponent. + * Scope annotation for singleton items within the {@link KeyguardBouncerComponent}. */ @Documented @Retention(RUNTIME) diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java index f498ef3466ef..394d63171b39 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java @@ -24,7 +24,7 @@ import java.lang.annotation.Retention; import javax.inject.Scope; /** - * Scope annotation for singleton items within the CentralSurfacesComponent. + * Scope annotation for singleton items within the {@link KeyguardStatusBarViewComponent}. */ @Documented @Retention(RUNTIME) diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java index aeae8e3d4b27..6c2c9f2d8e2f 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java @@ -24,7 +24,7 @@ import java.lang.annotation.Retention; import javax.inject.Scope; /** - * Scope annotation for singleton items within the CentralSurfacesComponent. + * Scope annotation for singleton items within the {@link KeyguardStatusViewComponent}. */ @Documented @Retention(RUNTIME) diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java index f29077d00439..e1612b071458 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java @@ -38,7 +38,7 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate; import com.android.internal.accessibility.dialog.AccessibilityTarget; -import com.android.systemui.aconfig.Flags; +import com.android.systemui.Flags; import java.util.ArrayList; import java.util.Collections; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java index 3822936d5d8e..df2c05d9f53c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java @@ -34,8 +34,8 @@ import android.view.WindowMetrics; import androidx.annotation.DimenRes; +import com.android.systemui.Flags; import com.android.systemui.R; -import com.android.systemui.aconfig.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java index cc18c305a112..1f549525256b 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java @@ -24,7 +24,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; -import com.android.systemui.aconfig.Flags; +import com.android.systemui.Flags; import com.android.systemui.util.settings.SecureSettings; /** diff --git a/packages/SystemUI/src/com/android/systemui/aconfig/AConfigModule.kt b/packages/SystemUI/src/com/android/systemui/aconfig/AConfigModule.kt index 251a699be38c..fa61bba6922d 100644 --- a/packages/SystemUI/src/com/android/systemui/aconfig/AConfigModule.kt +++ b/packages/SystemUI/src/com/android/systemui/aconfig/AConfigModule.kt @@ -16,6 +16,8 @@ package com.android.systemui.aconfig +import com.android.systemui.FeatureFlags +import com.android.systemui.FeatureFlagsImpl import com.android.systemui.dagger.SysUISingleton import dagger.Module import dagger.Provides diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 165bb6c6f68c..f26404cad02b 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -154,12 +154,12 @@ public class AssistManager { new IVisualQueryDetectionAttentionListener.Stub() { @Override public void onAttentionGained() { - mVisualQueryAttentionListeners.forEach(VisualQueryAttentionListener::onAttentionGained); + handleVisualAttentionChanged(true); } @Override public void onAttentionLost() { - mVisualQueryAttentionListeners.forEach(VisualQueryAttentionListener::onAttentionLost); + handleVisualAttentionChanged(false); } }; @@ -433,11 +433,21 @@ public class AssistManager { @Override public void onStopPerceiving() { + // Treat this as a signal that attention has been lost (and inform listeners + // accordingly). + handleVisualAttentionChanged(false); mAssistUtils.disableVisualQueryDetection(); } }); } + private void handleVisualAttentionChanged(boolean attentionGained) { + mVisualQueryAttentionListeners.forEach( + attentionGained + ? VisualQueryAttentionListener::onAttentionGained + : VisualQueryAttentionListener::onAttentionLost); + } + public void launchVoiceAssistFromKeyguard() { mAssistUtils.launchVoiceAssistFromKeyguard(); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt index 0d7d9cc9c9e5..017ac6019b65 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt @@ -446,7 +446,9 @@ private fun LottieAnimationView.addOverlayDynamicColor( for (key in listOf(".blue600", ".blue400")) { addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) { PorterDuffColorFilter( - context.getColor(com.android.settingslib.R.color.settingslib_color_blue400), + context.getColor( + com.android.settingslib.color.R.color.settingslib_color_blue400 + ), PorterDuff.Mode.SRC_ATOP ) } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java index 35624770b712..7b58b1fe3014 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java @@ -40,6 +40,7 @@ import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; import com.android.systemui.rotationlock.RotationLockModule; +import com.android.systemui.scene.SceneContainerFrameworkModule; import com.android.systemui.screenshot.ReferenceScreenshotModule; import com.android.systemui.settings.dagger.MultiUserUtilsModule; import com.android.systemui.shade.NotificationShadeWindowControllerImpl; @@ -57,6 +58,7 @@ import com.android.systemui.statusbar.phone.DozeServiceHost; import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; +import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentStartableModule; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.AospPolicyModule; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -95,6 +97,7 @@ import javax.inject.Named; @Module(includes = { AospPolicyModule.class, BatterySaverModule.class, + CollapsedStatusBarFragmentStartableModule.class, GestureModule.class, MediaModule.class, MultiUserUtilsModule.class, @@ -102,6 +105,7 @@ import javax.inject.Named; QSModule.class, ReferenceScreenshotModule.class, RotationLockModule.class, + SceneContainerFrameworkModule.class, StatusBarEventsModule.class, StartCentralSurfacesModule.class, VolumeModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index ade768486f08..08d11c2fc4ef 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -76,7 +76,6 @@ import com.android.systemui.qs.QSFragmentStartableModule; import com.android.systemui.qs.footer.dagger.FooterActionsModule; import com.android.systemui.recents.Recents; import com.android.systemui.retail.dagger.RetailModeModule; -import com.android.systemui.scene.SceneContainerFrameworkModule; import com.android.systemui.scene.ui.view.WindowRootViewComponent; import com.android.systemui.screenrecord.ScreenRecordModule; import com.android.systemui.screenshot.dagger.ScreenshotModule; @@ -109,7 +108,6 @@ import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfC import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.LetterboxModule; import com.android.systemui.statusbar.phone.NotificationIconAreaControllerModule; -import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; import com.android.systemui.statusbar.pipeline.dagger.StatusBarPipelineModule; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -196,7 +194,6 @@ import javax.inject.Named; QRCodeScannerModule.class, QSFragmentStartableModule.class, RetailModeModule.class, - SceneContainerFrameworkModule.class, ScreenshotModule.class, SensorModule.class, SecurityRepositoryModule.class, @@ -219,7 +216,6 @@ import javax.inject.Named; WalletModule.class }, subcomponents = { - CentralSurfacesComponent.class, ComplicationComponent.class, NavigationBarComponent.class, NotificationRowComponent.class, diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 74b9b092ecf2..d8b31a229261 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -43,6 +43,10 @@ object Flags { val ADD_TRANSIENT_HUN_IN_STACK_STATE_ANIMATOR = unreleasedFlag("add_transient_hun_in_stack_state_animator", teamfood = false) + // TODO(b/298308067): Tracking Bug + val SWIPE_UNCLEARED_TRANSIENT_VIEW_FIX = + unreleasedFlag("swipe_uncleared_transient_view_fix", teamfood = false) + // TODO(b/254512751): Tracking Bug val NOTIFICATION_PIPELINE_DEVELOPER_LOGGING = unreleasedFlag("notification_pipeline_developer_logging") @@ -210,7 +214,8 @@ object Flags { /** Inflate and bind views upon emitting a blueprint value . */ // TODO(b/297365780): Tracking Bug - @JvmField val LAZY_INFLATE_KEYGUARD = unreleasedFlag("lazy_inflate_keyguard") + @JvmField + val LAZY_INFLATE_KEYGUARD = unreleasedFlag("lazy_inflate_keyguard", teamfood = true) /** Enables UI updates for AI wallpapers in the wallpaper picker. */ // TODO(b/267722622): Tracking Bug @@ -767,7 +772,7 @@ object Flags { /** Enable the share wifi button in Quick Settings internet dialog. */ @JvmField - val SHARE_WIFI_QS_BUTTON = unreleasedFlag("share_wifi_qs_button") + val SHARE_WIFI_QS_BUTTON = unreleasedFlag("share_wifi_qs_button", teamfood = true) /** Enable haptic slider component in the brightness slider */ @JvmField diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 6bc9abf13cf7..257006e13201 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -126,11 +126,11 @@ constructor( } override fun start() { + bindKeyguardRootView() if (featureFlags.isEnabled(Flags.LAZY_INFLATE_KEYGUARD)) { keyguardRootView.removeAllViews() initializeViews() } else { - bindKeyguardRootView() val notificationPanel = notificationShadeWindowView.requireViewById(R.id.notification_panel) as ViewGroup unbindKeyguardBottomArea(notificationPanel) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 0c05a0e33871..e374549b9101 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -15,6 +15,8 @@ * */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.android.systemui.keyguard.domain.interactor import android.app.StatusBarManager @@ -42,10 +44,14 @@ import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.ScreenModel import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.WakefulnessModel +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.CommandQueue import com.android.systemui.util.kotlin.sample import javax.inject.Inject +import javax.inject.Provider +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow @@ -74,6 +80,7 @@ constructor( bouncerRepository: KeyguardBouncerRepository, configurationRepository: ConfigurationRepository, shadeRepository: ShadeRepository, + sceneInteractorProvider: Provider<SceneInteractor>, ) { /** Position information for the shared notification container. */ val sharedNotificationContainerPosition = @@ -187,7 +194,7 @@ constructor( combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded } /** Whether camera is launched over keyguard. */ - var isSecureCameraActive = + val isSecureCameraActive: Flow<Boolean> by lazy { if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) { combine( isKeyguardVisible, @@ -204,6 +211,7 @@ constructor( } else { flowOf(false) } + } /** The approximate location on the screen of the fingerprint sensor, if one is available. */ val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation @@ -240,11 +248,29 @@ constructor( } /** Whether to animate the next doze mode transition. */ - val animateDozingTransitions: Flow<Boolean> = repository.animateBottomAreaDozingTransitions + val animateDozingTransitions: Flow<Boolean> by lazy { + if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) { + sceneInteractorProvider + .get() + .transitioningTo + .map { it == SceneKey.Lockscreen } + .distinctUntilChanged() + .flatMapLatest { isTransitioningToLockscreenScene -> + if (isTransitioningToLockscreenScene) { + flowOf(false) + } else { + repository.animateBottomAreaDozingTransitions + } + } + } else { + repository.animateBottomAreaDozingTransitions + } + } fun dozeTransitionTo(vararg states: DozeStateModel): Flow<DozeTransitionModel> { return dozeTransitionModel.filter { states.contains(it.to) } } + fun isKeyguardShowing(): Boolean { return repository.isKeyguardShowing() } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index 28147325c609..8b0b0ae543a7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -78,6 +78,22 @@ object KeyguardRootViewBinder { } if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { + launch { viewModel.alpha.collect { alpha -> view.alpha = alpha } } + } + + if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { + launch { + viewModel.translationY.collect { + val statusView = + view.requireViewById<View>(R.id.keyguard_status_view) + statusView.translationY = it + } + } + } + } + + repeatOnLifecycle(Lifecycle.State.STARTED) { + if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { launch { viewModel.keyguardRootViewVisibilityState.collect { visibilityState -> view.animate().cancel() @@ -111,18 +127,6 @@ object KeyguardRootViewBinder { } } } - - launch { viewModel.alpha.collect { alpha -> view.alpha = alpha } } - } - - if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { - launch { - viewModel.translationY.collect { - val statusView = - view.requireViewById<View>(R.id.keyguard_status_view) - statusView.translationY = it - } - } } } } diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java index 5127d142d783..6c2ce7fa5156 100644 --- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java @@ -80,6 +80,14 @@ public class LogModule { return factory.create("NotifHeadsUpLog", 1000); } + /** Provides a logging buffer for logs related to inflation of notifications. */ + @Provides + @SysUISingleton + @NotifInflationLog + public static LogBuffer provideNotifInflationLogBuffer(LogBufferFactory factory) { + return factory.create("NotifInflationLog", 100); + } + /** Provides a logging buffer for notification interruption calculations. */ @Provides @SysUISingleton diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInflationLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInflationLog.java new file mode 100644 index 000000000000..9f201c377850 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotifInflationLog.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.log.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.android.systemui.log.LogBuffer; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +/** A {@link LogBuffer} for messages related to inflation of notifications. */ +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface NotifInflationLog { +} diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index a9d2b30c2b6f..4be572f8c0f6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -55,7 +55,6 @@ import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver; import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDisabledDialog; -import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.screenrecord.MediaProjectionPermissionDialog; import com.android.systemui.screenrecord.ScreenShareOption; import com.android.systemui.statusbar.phone.SystemUIDialog; @@ -73,7 +72,6 @@ public class MediaProjectionPermissionActivity extends Activity private final FeatureFlags mFeatureFlags; private final Lazy<ScreenCaptureDevicePolicyResolver> mScreenCaptureDevicePolicyResolver; - private final ActivityStarter mActivityStarter; private String mPackageName; private int mUid; @@ -89,10 +87,8 @@ public class MediaProjectionPermissionActivity extends Activity @Inject public MediaProjectionPermissionActivity(FeatureFlags featureFlags, - Lazy<ScreenCaptureDevicePolicyResolver> screenCaptureDevicePolicyResolver, - ActivityStarter activityStarter) { + Lazy<ScreenCaptureDevicePolicyResolver> screenCaptureDevicePolicyResolver) { mFeatureFlags = featureFlags; - mActivityStarter = activityStarter; mScreenCaptureDevicePolicyResolver = screenCaptureDevicePolicyResolver; } @@ -313,16 +309,8 @@ public class MediaProjectionPermissionActivity extends Activity // Start activity from the current foreground user to avoid creating a separate // SystemUI process without access to recent tasks because it won't have // WM Shell running inside. - // It is also important to make sure the shade is dismissed, otherwise users won't - // see the app selector. mUserSelectingTask = true; - mActivityStarter.startActivity( - intent, - /* dismissShade= */ true, - /* animationController= */ null, - /* showOverLockscreenWhenLocked= */ false, - UserHandle.of(ActivityManager.getCurrentUser()) - ); + startActivityAsUser(intent, UserHandle.of(ActivityManager.getCurrentUser())); } } catch (RemoteException e) { Log.e(TAG, "Error granting projection permission", e); diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt index bbb61b4d1745..ec0c40ec69a3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt @@ -26,6 +26,7 @@ import android.view.ViewOutlineProvider import androidx.core.view.GestureDetectorCompat import androidx.dynamicanimation.animation.FloatPropertyCompat import androidx.dynamicanimation.animation.SpringForce +import com.android.internal.annotations.VisibleForTesting import com.android.settingslib.Utils import com.android.systemui.Gefingerpoken import com.android.systemui.R @@ -146,7 +147,8 @@ class MediaCarouselScrollHandler( } /** The touch listener for the scroll view */ - private val touchListener = + @VisibleForTesting + val touchListener = object : Gefingerpoken { override fun onTouchEvent(motionEvent: MotionEvent?) = onTouch(motionEvent!!) override fun onInterceptTouchEvent(ev: MotionEvent?) = onInterceptTouch(ev!!) @@ -279,15 +281,14 @@ class MediaCarouselScrollHandler( } else if (isUp || motionEvent.action == MotionEvent.ACTION_CANCEL) { // It's an up and the fling didn't take it above val relativePos = scrollView.relativeScrollX % playerWidthPlusPadding - val scrollXAmount: Int - if (relativePos > playerWidthPlusPadding / 2) { - scrollXAmount = playerWidthPlusPadding - relativePos - } else { - scrollXAmount = -1 * relativePos - } + val scrollXAmount: Int = + if (isRtl xor (relativePos > playerWidthPlusPadding / 2)) { + playerWidthPlusPadding - relativePos + } else { + -1 * relativePos + } if (scrollXAmount != 0) { - val dx = if (isRtl) -scrollXAmount else scrollXAmount - val newScrollX = scrollView.relativeScrollX + dx + val newScrollX = scrollView.relativeScrollX + scrollXAmount // Delay the scrolling since scrollView calls springback which cancels // the animation again.. mainExecutor.execute { scrollView.smoothScrollTo(newScrollX, scrollView.scrollY) } diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java index 8d3b7451c90b..1d820a14be4e 100644 --- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java @@ -70,6 +70,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceManager; @@ -85,9 +86,11 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.systemui.Dumpable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; +import com.android.systemui.dump.DumpManager; import com.android.systemui.people.NotificationHelper; import com.android.systemui.people.PeopleBackupFollowUpJob; import com.android.systemui.people.PeopleSpaceUtils; @@ -99,6 +102,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.wm.shell.bubbles.Bubbles; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -119,7 +123,8 @@ import javax.inject.Inject; /** Manager for People Space widget. */ @SysUISingleton -public class PeopleSpaceWidgetManager { +public class PeopleSpaceWidgetManager implements Dumpable { + private static final String TAG = "PeopleSpaceWidgetMgr"; private static final boolean DEBUG = PeopleSpaceUtils.DEBUG; @@ -160,7 +165,8 @@ public class PeopleSpaceWidgetManager { CommonNotifCollection notifCollection, PackageManager packageManager, Optional<Bubbles> bubblesOptional, UserManager userManager, NotificationManager notificationManager, - BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor) { + BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor, + DumpManager dumpManager) { if (DEBUG) Log.d(TAG, "constructor"); mContext = context; mAppWidgetManager = AppWidgetManager.getInstance(context); @@ -180,6 +186,7 @@ public class PeopleSpaceWidgetManager { mManager = this; mBroadcastDispatcher = broadcastDispatcher; mBgExecutor = bgExecutor; + dumpManager.registerNormalDumpable(TAG, this); } /** Initializes {@PeopleSpaceWidgetManager}. */ @@ -1364,4 +1371,40 @@ public class PeopleSpaceWidgetManager { .filter(id -> !TextUtils.isEmpty(id)) .collect(Collectors.toSet()); } + + @Override + public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { + Trace.traceBegin(Trace.TRACE_TAG_APP, TAG + ".dump"); + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + Map<String, ?> all = sp.getAll(); + pw.println("People widget list:"); + for (Map.Entry<String, ?> entry : all.entrySet()) { + String key = entry.getKey(); + PeopleBackupHelper.SharedFileEntryType keyType = getEntryType(entry); + switch (keyType) { + case WIDGET_ID: + SharedPreferences widgetSp = mContext.getSharedPreferences(key, + Context.MODE_PRIVATE); + pw.print("People widget (valid) ["); + pw.print(key); + pw.print("] shortcut id: \""); + pw.print(widgetSp.getString(SHORTCUT_ID, EMPTY_STRING)); + pw.print("\", user id: "); + pw.print(widgetSp.getInt(USER_ID, INVALID_USER_ID)); + pw.print(", package: "); + pw.println(widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)); + break; + case PEOPLE_TILE_KEY: + case CONTACT_URI: + pw.print("Extra data ["); + pw.print(key); + pw.print(" : "); + pw.print((Set<String>) entry.getValue()); + pw.println("]"); + break; + } + } + + Trace.traceEnd(Trace.TRACE_TAG_APP); + } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING index 86ef7ef2ebce..66f020f24e80 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING +++ b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING @@ -10,7 +10,9 @@ "exclude-annotation": "androidx.test.filters.FlakyTest" } ] - }, + } + ], + "postsubmit": [ { "name": "QuickSettingsDeviceResetTests", "options": [ diff --git a/packages/SystemUI/src/com/android/systemui/scene/EmptySceneModule.kt b/packages/SystemUI/src/com/android/systemui/scene/EmptySceneModule.kt new file mode 100644 index 000000000000..efb9375a21f0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/scene/EmptySceneModule.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import com.android.systemui.scene.shared.model.Scene +import dagger.Module +import dagger.Provides +import dagger.multibindings.ElementsIntoSet + +@Module +object EmptySceneModule { + + @Provides + @ElementsIntoSet + fun emptySceneSet(): Set<Scene> { + return emptySet() + } +} diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt new file mode 100644 index 000000000000..c5fbf7b96fff --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.scene + +import com.android.systemui.scene.shared.model.SceneContainerConfig +import com.android.systemui.scene.shared.model.SceneKey +import dagger.Module +import dagger.Provides + +/** Scene framework Dagger module suitable for variants that want to exclude "keyguard" scenes. */ +@Module( + includes = + [ + EmptySceneModule::class, + GoneSceneModule::class, + QuickSettingsSceneModule::class, + ShadeSceneModule::class, + ], +) +object KeyguardlessSceneContainerFrameworkModule { + + // TODO(b/298234162): provide a SceneContainerStartable without lockscreen and bouncer. + + @Provides + fun containerConfig(): SceneContainerConfig { + return SceneContainerConfig( + // Note that this list is in z-order. The first one is the bottom-most and the + // last one is top-most. + sceneKeys = + listOf( + SceneKey.Gone, + SceneKey.Shade, + SceneKey.QuickSettings, + ), + initialSceneKey = SceneKey.Gone, + ) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt index 714795109454..85ef21aa9542 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt @@ -16,19 +16,60 @@ package com.android.systemui.scene -import com.android.systemui.keyguard.ui.view.LockscreenSceneModule -import com.android.systemui.scene.domain.startable.SceneContainerStartableModule -import com.android.systemui.scene.shared.model.SceneContainerConfigModule -import com.android.systemui.scene.ui.composable.SceneModule +import com.android.systemui.CoreStartable +import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor +import com.android.systemui.scene.domain.startable.SceneContainerStartable +import com.android.systemui.scene.shared.model.SceneContainerConfig +import com.android.systemui.scene.shared.model.SceneKey +import dagger.Binds import dagger.Module +import dagger.Provides +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +/** Scene framework Dagger module suitable for AOSP. */ @Module( includes = [ + BouncerSceneModule::class, + EmptySceneModule::class, + GoneSceneModule::class, LockscreenSceneModule::class, - SceneContainerConfigModule::class, - SceneContainerStartableModule::class, - SceneModule::class, + QuickSettingsSceneModule::class, + ShadeSceneModule::class, ], ) -object SceneContainerFrameworkModule +interface SceneContainerFrameworkModule { + + @Binds + @IntoMap + @ClassKey(SceneContainerStartable::class) + fun containerStartable(impl: SceneContainerStartable): CoreStartable + + @Binds + @IntoMap + @ClassKey(WindowRootViewVisibilityInteractor::class) + fun bindWindowRootViewVisibilityInteractor( + impl: WindowRootViewVisibilityInteractor + ): CoreStartable + + companion object { + + @Provides + fun containerConfig(): SceneContainerConfig { + return SceneContainerConfig( + // Note that this list is in z-order. The first one is the bottom-most and the + // last one is top-most. + sceneKeys = + listOf( + SceneKey.Gone, + SceneKey.Lockscreen, + SceneKey.Bouncer, + SceneKey.Shade, + SceneKey.QuickSettings, + ), + initialSceneKey = SceneKey.Lockscreen, + ) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt index f74005b03816..5fda9b1a323b 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,27 +14,37 @@ * limitations under the License. */ -package com.android.systemui.scene.shared.model +package com.android.systemui.scene +import com.android.systemui.scene.shared.model.SceneContainerConfig +import com.android.systemui.scene.shared.model.SceneKey import dagger.Module import dagger.Provides -@Module -object SceneContainerConfigModule { +/** Scene framework Dagger module suitable for variants that want to exclude "shade" scenes. */ +@Module( + includes = + [ + BouncerSceneModule::class, + EmptySceneModule::class, + GoneSceneModule::class, + LockscreenSceneModule::class, + ], +) +object ShadelessSceneContainerFrameworkModule { + + // TODO(b/298229861): provide a version of SceneContainerStartable without shade and qs. @Provides fun containerConfig(): SceneContainerConfig { return SceneContainerConfig( // Note that this list is in z-order. The first one is the bottom-most and the - // last - // one is top-most. + // last one is top-most. sceneKeys = listOf( SceneKey.Gone, SceneKey.Lockscreen, SceneKey.Bouncer, - SceneKey.Shade, - SceneKey.QuickSettings, ), initialSceneKey = SceneKey.Lockscreen, ) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt index 2ad71e7d989d..80274bde6ce2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt @@ -27,6 +27,7 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom import com.android.systemui.statusbar.window.StatusBarWindowController import java.lang.IllegalStateException import javax.inject.Inject +import javax.inject.Provider /** * Responsible for creating the status bar window and initializing the root components of that @@ -35,6 +36,7 @@ import javax.inject.Inject @SysUISingleton class StatusBarInitializer @Inject constructor( private val windowController: StatusBarWindowController, + private val collapsedStatusBarFragmentProvider: Provider<CollapsedStatusBarFragment>, private val creationListeners: Set<@JvmSuppressWildcards OnStatusBarViewInitializedListener>, ) { @@ -43,11 +45,9 @@ class StatusBarInitializer @Inject constructor( /** * Creates the status bar window and root views, and initializes the component. * - * TODO(b/277762009): Inject StatusBarFragmentCreator and make this class a CoreStartable. + * TODO(b/277764509): Initialize the status bar via [CoreStartable#start]. */ - fun initializeStatusBar( - statusBarFragmentCreator: () -> CollapsedStatusBarFragment, - ) { + fun initializeStatusBar() { windowController.fragmentHostManager.addTagListener( CollapsedStatusBarFragment.TAG, object : FragmentHostManager.FragmentListener { @@ -67,11 +67,14 @@ class StatusBarInitializer @Inject constructor( override fun onFragmentViewDestroyed(tag: String?, fragment: Fragment?) { // nop } - }).fragmentManager + } + ).fragmentManager .beginTransaction() - .replace(R.id.status_bar_container, - statusBarFragmentCreator.invoke(), - CollapsedStatusBarFragment.TAG) + .replace( + R.id.status_bar_container, + collapsedStatusBarFragmentProvider.get(), + CollapsedStatusBarFragment.TAG + ) .commit() } 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 d24896148095..6e3b15da4423 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt @@ -34,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.BindEven import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.row.NotificationContentInflaterLogger import com.android.systemui.statusbar.notification.row.NotificationContentView import com.android.systemui.statusbar.notification.stack.StackStateAnimator import com.android.systemui.statusbar.policy.HeadsUpManager @@ -47,7 +48,11 @@ class ConversationNotificationProcessor @Inject constructor( private val launcherApps: LauncherApps, private val conversationNotificationManager: ConversationNotificationManager ) { - fun processNotification(entry: NotificationEntry, recoveredBuilder: Notification.Builder) { + fun processNotification( + entry: NotificationEntry, + recoveredBuilder: Notification.Builder, + logger: NotificationContentInflaterLogger + ) { val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return messagingStyle.conversationType = if (entry.ranking.channel.isImportantConversation) @@ -55,6 +60,7 @@ class ConversationNotificationProcessor @Inject constructor( else Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL entry.ranking.conversationShortcutInfo?.let { shortcutInfo -> + logger.logAsyncTaskProgress(entry, "getting shortcut icon") messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo) shortcutInfo.label?.let { label -> messagingStyle.conversationTitle = label diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java index d1aa01bb2125..98109f940289 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterImpl.java @@ -36,12 +36,14 @@ import javax.inject.Inject; public class NotifInflaterImpl implements NotifInflater { private final NotifInflationErrorManager mNotifErrorManager; + private final NotifInflaterLogger mLogger; private NotificationRowBinderImpl mNotificationRowBinder; @Inject - public NotifInflaterImpl(NotifInflationErrorManager errorManager) { + public NotifInflaterImpl(NotifInflationErrorManager errorManager, NotifInflaterLogger logger) { mNotifErrorManager = errorManager; + mLogger = logger; } /** @@ -51,12 +53,6 @@ public class NotifInflaterImpl implements NotifInflater { mNotificationRowBinder = rowBinder; } - @Override - public void rebindViews(@NonNull NotificationEntry entry, @NonNull Params params, - @NonNull InflationCallback callback) { - inflateViews(entry, params, callback); - } - /** * Called to inflate the views of an entry. Views are not considered inflated until all of its * views are bound. @@ -64,23 +60,43 @@ public class NotifInflaterImpl implements NotifInflater { @Override public void inflateViews(@NonNull NotificationEntry entry, @NonNull Params params, @NonNull InflationCallback callback) { + mLogger.logInflatingViews(entry, params); + inflateViewsImpl(entry, params, callback); + mLogger.logInflatedViews(entry); + } + @Override + public void rebindViews(@NonNull NotificationEntry entry, @NonNull Params params, + @NonNull InflationCallback callback) { + mLogger.logRebindingViews(entry, params); + inflateViewsImpl(entry, params, callback); + mLogger.logReboundViews(entry); + } + + private void inflateViewsImpl(@NonNull NotificationEntry entry, @NonNull Params params, + @NonNull InflationCallback callback) { try { requireBinder().inflateViews( entry, params, wrapInflationCallback(callback)); } catch (InflationException e) { + mLogger.logInflationException(entry, e); mNotifErrorManager.setInflationError(entry, e); } } @Override public boolean abortInflation(NotificationEntry entry) { - return entry.abortTask(); + final boolean abortedTask = entry.abortTask(); + if (abortedTask) { + mLogger.logAbortInflationAbortedTask(entry); + } + return abortedTask; } @Override public void releaseViews(@NonNull NotificationEntry entry) { + mLogger.logReleasingViews(entry); requireBinder().releaseViews(entry); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterLogger.kt new file mode 100644 index 000000000000..366c7d329662 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifInflaterLogger.kt @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.core.LogLevel +import com.android.systemui.log.dagger.NotifInflationLog +import com.android.systemui.statusbar.notification.InflationException +import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater.Params +import com.android.systemui.statusbar.notification.logKey +import javax.inject.Inject + +class NotifInflaterLogger @Inject constructor(@NotifInflationLog private val buffer: LogBuffer) { + fun logInflatingViews(entry: NotificationEntry, params: Params) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = params.reason + }, + { "inflating views for $str1: $str2" } + ) + } + + fun logInflatedViews(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "inflated views for $str1" }) + } + + fun logRebindingViews(entry: NotificationEntry, params: Params) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = params.reason + }, + { "rebinding views for $str1: $str2" } + ) + } + + fun logReboundViews(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "rebound views for $str1" }) + } + + fun logInflationException(entry: NotificationEntry, exc: InflationException) { + buffer.log( + TAG, + LogLevel.WARNING, + { + str1 = entry.logKey + str2 = exc.stackTraceToString() + }, + { "exception inflating views for $str1: $str2" } + ) + } + + fun logAbortInflationAbortedTask(entry: NotificationEntry) { + buffer.log( + TAG, + LogLevel.DEBUG, + { str1 = entry.logKey }, + { "aborted task to abort inflation for $str1" } + ) + } + + fun logReleasingViews(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "aborting inflation for $str1" }) + } +} + +private const val TAG = "NotifInflater" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt index 5c2f9a8d28ec..62a0d138fd05 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt @@ -39,10 +39,7 @@ class StackCoordinator @Inject internal constructor( override fun attach(pipeline: NotifPipeline) { pipeline.addOnAfterRenderListListener(::onAfterRenderList) - // TODO(b/282865576): This has an issue where it makes changes to some groups without - // notifying listeners. To be fixed in QPR, but for now let's comment it out to avoid the - // group expansion bug. - // groupExpansionManagerImpl.attach(pipeline) + groupExpansionManagerImpl.attach(pipeline) } fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index 9ecf50ee4f8c..e20614178885 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -67,6 +67,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { private final ExpandableNotificationRowComponent.Builder mExpandableNotificationRowComponentBuilder; private final IconManager mIconManager; + private final NotificationRowBinderLogger mLogger; private NotificationPresenter mPresenter; private NotificationListContainer mListContainer; @@ -84,6 +85,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { Provider<RowInflaterTask> rowInflaterTaskProvider, ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder, IconManager iconManager, + NotificationRowBinderLogger logger, FeatureFlags featureFlags) { mContext = context; mNotifBindPipeline = notifBindPipeline; @@ -94,6 +96,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { mRowInflaterTaskProvider = rowInflaterTaskProvider; mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder; mIconManager = iconManager; + mLogger = logger; mFeatureFlags = featureFlags; } @@ -124,15 +127,19 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { ViewGroup parent = mListContainer.getViewParentForNotification(entry); if (entry.rowExists()) { + mLogger.logUpdatingRow(entry, params); mIconManager.updateIcons(entry); ExpandableNotificationRow row = entry.getRow(); row.reset(); updateRow(entry, row); inflateContentViews(entry, params, row, callback); } else { + mLogger.logCreatingRow(entry, params); mIconManager.createIcons(entry); + mLogger.logInflatingRow(entry); mRowInflaterTaskProvider.get().inflate(mContext, parent, entry, row -> { + mLogger.logInflatedRow(entry); // Setup the controller for the view. ExpandableNotificationRowComponent component = mExpandableNotificationRowComponentBuilder @@ -154,8 +161,10 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { @Override public void releaseViews(NotificationEntry entry) { if (!entry.rowExists()) { + mLogger.logNotReleasingViewsRowDoesntExist(entry); return; } + mLogger.logReleasingViews(entry); final RowContentBindParams params = mRowContentBindStage.getStageParams(entry); params.markContentViewsFreeable(FLAG_CONTENT_VIEW_CONTRACTED); params.markContentViewsFreeable(FLAG_CONTENT_VIEW_EXPANDED); @@ -220,7 +229,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { } params.rebindAllContentViews(); + mLogger.logRequestingRebind(entry, inflaterParams); mRowContentBindStage.requestRebind(entry, en -> { + mLogger.logRebindComplete(entry); row.setUsesIncreasedCollapsedHeight(useIncreasedCollapsedHeight); row.setIsLowPriority(isLowPriority); if (inflationCallback != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderLogger.kt new file mode 100644 index 000000000000..7eafc59019d4 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderLogger.kt @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.inflation + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.core.LogLevel +import com.android.systemui.log.dagger.NotifInflationLog +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater.Params +import com.android.systemui.statusbar.notification.logKey +import javax.inject.Inject + +class NotificationRowBinderLogger +@Inject +constructor(@NotifInflationLog private val buffer: LogBuffer) { + fun logCreatingRow(entry: NotificationEntry, params: Params) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = params.reason + }, + { "creating row for $str1: $str2" } + ) + } + + fun logInflatingRow(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "inflating row for $str1" }) + } + + fun logInflatedRow(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "inflated row for $str1" }) + } + + fun logUpdatingRow(entry: NotificationEntry, params: Params) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = params.reason + }, + { "updating row for $str1: $str2" } + ) + } + + fun logReleasingViews(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.logKey }, { "releasing views for $str1" }) + } + + fun logNotReleasingViewsRowDoesntExist(entry: NotificationEntry) { + buffer.log( + TAG, + LogLevel.DEBUG, + { str1 = entry.logKey }, + { "not releasing views for $str1: row doesn't exist" } + ) + } + + fun logRequestingRebind(entry: NotificationEntry, params: Params) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.key + str2 = params.reason + }, + { "requesting rebind for $str1: $str2" } + ) + } + + fun logRebindComplete(entry: NotificationEntry) { + buffer.log(TAG, LogLevel.DEBUG, { str1 = entry.key }, { "rebind complete for $str1" }) + } +} + +private const val TAG = "NotificationRowBinder" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java index 46af03a438f5..eb31bd3a95fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java @@ -67,18 +67,29 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl * Cleanup entries from mExpandedGroups that no longer exist in the pipeline. */ private final OnBeforeRenderListListener mNotifTracker = (entries) -> { + if (mExpandedGroups.isEmpty()) { + return; // nothing to do + } + final Set<NotificationEntry> renderingSummaries = new HashSet<>(); for (ListEntry entry : entries) { if (entry instanceof GroupEntry) { renderingSummaries.add(entry.getRepresentativeEntry()); } } - mExpandedGroups.removeIf(expandedGroup -> !renderingSummaries.contains(expandedGroup)); + + // If a group is in mExpandedGroups but not in the pipeline entries, collapse it. + final var groupsToRemove = setDifference(mExpandedGroups, renderingSummaries); + for (NotificationEntry entry : groupsToRemove) { + setGroupExpanded(entry, false); + } }; public void attach(NotifPipeline pipeline) { - mDumpManager.registerDumpable(this); - pipeline.addOnBeforeRenderListListener(mNotifTracker); + if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) { + mDumpManager.registerDumpable(this); + pipeline.addOnBeforeRenderListListener(mNotifTracker); + } } @Override @@ -134,4 +145,27 @@ public class GroupExpansionManagerImpl implements GroupExpansionManager, Dumpabl listener.onGroupExpansionChange(entry.getRow(), expanded); } } + + /** + * Utility method to compute the difference between two sets of NotificationEntry. Unfortunately + * {@code Sets.difference} from Guava is not available in this codebase. + */ + @NonNull + private Set<NotificationEntry> setDifference(Set<NotificationEntry> set1, + Set<NotificationEntry> set2) { + if (set1 == null || set1.isEmpty()) { + return new HashSet<>(); + } + if (set2 == null || set2.isEmpty()) { + return new HashSet<>(set1); + } + + final Set<NotificationEntry> difference = new HashSet<>(); + for (NotificationEntry e : set1) { + if (!set2.contains(e)) { + difference.add(e); + } + } + return difference; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java index b9c8f7223740..c33e8ab8cdd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.notification.collection.render; +import android.annotation.NonNull; import android.annotation.Nullable; import com.android.systemui.statusbar.notification.collection.ListEntry; @@ -31,13 +32,14 @@ public interface GroupMembershipManager { * @return whether a given notification is a top level entry or is the summary in a group which * has children */ - boolean isGroupSummary(NotificationEntry entry); + boolean isGroupSummary(@NonNull NotificationEntry entry); /** * Get the summary of a specified status bar notification. For an isolated notification this * returns itself. */ - NotificationEntry getGroupSummary(NotificationEntry entry); + @Nullable + NotificationEntry getGroupSummary(@NonNull NotificationEntry entry); /** * Similar to {@link #getGroupSummary(NotificationEntry)} but doesn't get the visual summary @@ -46,19 +48,20 @@ public interface GroupMembershipManager { * TODO: remove this when migrating to the new pipeline, this is taken care of in the * dismissal logic built into NotifCollection */ - default NotificationEntry getLogicalGroupSummary(NotificationEntry entry) { + @Nullable + default NotificationEntry getLogicalGroupSummary(@NonNull NotificationEntry entry) { return getGroupSummary(entry); } /** * @return whether a given notification is a child in a group */ - boolean isChildInGroup(NotificationEntry entry); + boolean isChildInGroup(@NonNull NotificationEntry entry); /** * Whether this is the only child in a group */ - boolean isOnlyChildInGroup(NotificationEntry entry); + boolean isOnlyChildInGroup(@NonNull NotificationEntry entry); /** * Get the children that are in the summary's group, not including those isolated. @@ -67,5 +70,5 @@ public interface GroupMembershipManager { * @return list of the children */ @Nullable - List<NotificationEntry> getChildren(ListEntry summary); + List<NotificationEntry> getChildren(@NonNull ListEntry summary); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java index e784ec62c8e6..a6b855f9b838 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java @@ -18,40 +18,65 @@ package com.android.systemui.statusbar.notification.collection.render; import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.statusbar.notification.collection.GroupEntry; import com.android.systemui.statusbar.notification.collection.ListEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import java.util.List; +import javax.inject.Inject; + /** * ShadeListBuilder groups notifications from system server. This manager translates * ShadeListBuilder's method of grouping to be used within SystemUI. */ +@SysUISingleton public class GroupMembershipManagerImpl implements GroupMembershipManager { + FeatureFlags mFeatureFlags; + + @Inject + public GroupMembershipManagerImpl(FeatureFlags featureFlags) { + mFeatureFlags = featureFlags; + } + @Override - public boolean isGroupSummary(NotificationEntry entry) { + public boolean isGroupSummary(@NonNull NotificationEntry entry) { return getGroupSummary(entry) == entry; } + @Nullable @Override - public NotificationEntry getGroupSummary(NotificationEntry entry) { - if (isEntryTopLevel(entry) || entry.getParent() == null) { - return null; + public NotificationEntry getGroupSummary(@NonNull NotificationEntry entry) { + if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) { + if (!isChildInGroup(entry)) { + return entry.getRepresentativeEntry(); + } + } else { + if (isEntryTopLevel(entry) || entry.getParent() == null) { + return null; + } } return entry.getParent().getRepresentativeEntry(); } @Override - public boolean isChildInGroup(NotificationEntry entry) { - return !isEntryTopLevel(entry); + public boolean isChildInGroup(@NonNull NotificationEntry entry) { + if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) { + return !isEntryTopLevel(entry) && entry.getParent() != null; + } else { + return !isEntryTopLevel(entry); + } } @Override - public boolean isOnlyChildInGroup(NotificationEntry entry) { + public boolean isOnlyChildInGroup(@NonNull NotificationEntry entry) { if (entry.getParent() == null) { return false; } @@ -61,20 +86,24 @@ public class GroupMembershipManagerImpl implements GroupMembershipManager { @Nullable @Override - public List<NotificationEntry> getChildren(ListEntry entry) { + public List<NotificationEntry> getChildren(@NonNull ListEntry entry) { if (entry instanceof GroupEntry) { return ((GroupEntry) entry).getChildren(); } - if (isGroupSummary(entry.getRepresentativeEntry())) { + NotificationEntry representativeEntry = entry.getRepresentativeEntry(); + if (representativeEntry != null && isGroupSummary(representativeEntry)) { // maybe we were actually passed the summary - return entry.getRepresentativeEntry().getParent().getChildren(); + GroupEntry parent = representativeEntry.getParent(); + if (parent != null) { + return parent.getChildren(); + } } return null; } - private boolean isEntryTopLevel(NotificationEntry entry) { + private boolean isEntryTopLevel(@NonNull NotificationEntry entry) { return entry.getParent() == ROOT_ENTRY; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 09be41b56a10..5664a2af7c0e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -167,11 +167,8 @@ public interface NotificationsModule { } /** Provides an instance of {@link GroupMembershipManager} */ - @SysUISingleton - @Provides - static GroupMembershipManager provideGroupMembershipManager() { - return new GroupMembershipManagerImpl(); - } + @Binds + GroupMembershipManager provideGroupMembershipManager(GroupMembershipManagerImpl impl); /** Provides an instance of {@link GroupExpansionManager} */ @Binds diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java index d2034d7a8564..8d2a63e9b3fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java @@ -276,14 +276,16 @@ public class NotificationLogger implements StateListener, CoreStartable { } } - @GuardedBy("mDozingLock") public void startNotificationLogging() { if (!mLogging) { mLogging = true; if (DEBUG) { Log.i(TAG, "startNotificationLogging"); } - boolean lockscreen = mLockscreen != null && mLockscreen; + boolean lockscreen; + synchronized (mDozingLock) { + lockscreen = mLockscreen != null && mLockscreen; + } mNotificationPanelLogger.logPanelShown(lockscreen, getVisibleNotifications()); mListContainer.setChildLocationsChangedListener(this::onChildLocationsChanged); // Sometimes, the transition from lockscreenOrShadeVisible=false -> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java index 86f545dc190e..f805183d52aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java @@ -80,6 +80,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder private final Executor mBgExecutor; private final SmartReplyStateInflater mSmartReplyStateInflater; private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider; + private final NotificationContentInflaterLogger mLogger; @Inject NotificationContentInflater( @@ -89,7 +90,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder MediaFeatureFlag mediaFeatureFlag, @Background Executor bgExecutor, SmartReplyStateInflater smartRepliesInflater, - NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider) { + NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider, + NotificationContentInflaterLogger logger) { mRemoteViewCache = remoteViewCache; mRemoteInputManager = remoteInputManager; mConversationProcessor = conversationProcessor; @@ -97,6 +99,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder mBgExecutor = bgExecutor; mSmartReplyStateInflater = smartRepliesInflater; mNotifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider; + mLogger = logger; } @Override @@ -111,9 +114,12 @@ public class NotificationContentInflater implements NotificationRowContentBinder // We don't want to reinflate anything for removed notifications. Otherwise views might // be readded to the stack, leading to leaks. This may happen with low-priority groups // where the removal of already removed children can lead to a reinflation. + mLogger.logNotBindingRowWasRemoved(entry); return; } + mLogger.logBinding(entry, contentToBind); + StatusBarNotification sbn = entry.getSbn(); // To check if the notification has inline image and preload inline image if necessary. @@ -141,7 +147,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder mRemoteInputManager.getRemoteViewsOnClickHandler(), mIsMediaInQS, mSmartReplyStateInflater, - mNotifLayoutInflaterFactoryProvider); + mNotifLayoutInflaterFactoryProvider, + mLogger); if (mInflateSynchronously) { task.onPostExecute(task.doInBackground()); } else { @@ -166,12 +173,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder bindParams.usesIncreasedHeadsUpHeight, packageContext, row, - mNotifLayoutInflaterFactoryProvider); + mNotifLayoutInflaterFactoryProvider, + mLogger); - result = inflateSmartReplyViews(result, reInflateFlags, entry, - row.getContext(), packageContext, - row.getExistingSmartReplyState(), - smartRepliesInflater); + result = inflateSmartReplyViews(result, reInflateFlags, entry, row.getContext(), + packageContext, row.getExistingSmartReplyState(), smartRepliesInflater, mLogger); apply( mBgExecutor, @@ -182,15 +188,20 @@ public class NotificationContentInflater implements NotificationRowContentBinder entry, row, mRemoteInputManager.getRemoteViewsOnClickHandler(), - null); + null /* callback */, + mLogger); return result; } @Override - public void cancelBind( + public boolean cancelBind( @NonNull NotificationEntry entry, @NonNull ExpandableNotificationRow row) { - entry.abortTask(); + final boolean abortedTask = entry.abortTask(); + if (abortedTask) { + mLogger.logCancelBindAbortedTask(entry); + } + return abortedTask; } @Override @@ -198,6 +209,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder @NonNull NotificationEntry entry, @NonNull ExpandableNotificationRow row, @InflationFlag int contentToUnbind) { + mLogger.logUnbinding(entry, contentToUnbind); int curFlag = 1; while (contentToUnbind != 0) { if ((contentToUnbind & curFlag) != 0) { @@ -279,7 +291,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder Context context, Context packageContext, InflatedSmartReplyState previousSmartReplyState, - SmartReplyStateInflater inflater) { + SmartReplyStateInflater inflater, + NotificationContentInflaterLogger logger) { boolean inflateContracted = (reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0 && result.newContentView != null; boolean inflateExpanded = (reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0 @@ -287,14 +300,17 @@ public class NotificationContentInflater implements NotificationRowContentBinder boolean inflateHeadsUp = (reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0 && result.newHeadsUpView != null; if (inflateContracted || inflateExpanded || inflateHeadsUp) { + logger.logAsyncTaskProgress(entry, "inflating contracted smart reply state"); result.inflatedSmartReplyState = inflater.inflateSmartReplyState(entry); } if (inflateExpanded) { + logger.logAsyncTaskProgress(entry, "inflating expanded smart reply state"); result.expandedInflatedSmartReplies = inflater.inflateSmartReplyViewHolder( context, packageContext, entry, previousSmartReplyState, result.inflatedSmartReplyState); } if (inflateHeadsUp) { + logger.logAsyncTaskProgress(entry, "inflating heads up smart reply state"); result.headsUpInflatedSmartReplies = inflater.inflateSmartReplyViewHolder( context, packageContext, entry, previousSmartReplyState, result.inflatedSmartReplyState); @@ -306,22 +322,28 @@ public class NotificationContentInflater implements NotificationRowContentBinder Notification.Builder builder, boolean isLowPriority, boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, Context packageContext, ExpandableNotificationRow row, - NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider) { + NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider, + NotificationContentInflaterLogger logger) { InflationProgress result = new InflationProgress(); + final NotificationEntry entryForLogging = row.getEntry(); if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { + logger.logAsyncTaskProgress(entryForLogging, "creating contracted remote view"); result.newContentView = createContentView(builder, isLowPriority, usesIncreasedHeight); } if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) { + logger.logAsyncTaskProgress(entryForLogging, "creating expanded remote view"); result.newExpandedView = createExpandedView(builder, isLowPriority); } if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) { + logger.logAsyncTaskProgress(entryForLogging, "creating heads up remote view"); result.newHeadsUpView = builder.createHeadsUpContentView(usesIncreasedHeadsUpHeight); } if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) { + logger.logAsyncTaskProgress(entryForLogging, "creating public remote view"); result.newPublicView = builder.makePublicContentView(isLowPriority); } setNotifsViewsInflaterFactory(result, row, notifLayoutInflaterFactoryProvider); @@ -361,7 +383,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder NotificationEntry entry, ExpandableNotificationRow row, RemoteViews.InteractionHandler remoteViewClickHandler, - @Nullable InflationCallback callback) { + @Nullable InflationCallback callback, + NotificationContentInflaterLogger logger) { NotificationContentView privateLayout = row.getPrivateLayout(); NotificationContentView publicLayout = row.getPublicLayout(); final HashMap<Integer, CancellationSignal> runningInflations = new HashMap<>(); @@ -374,6 +397,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder ApplyCallback applyCallback = new ApplyCallback() { @Override public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, "contracted view applied"); result.inflatedContentView = v; } @Override @@ -381,12 +405,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder return result.newContentView; } }; + logger.logAsyncTaskProgress(entry, "applying contracted view"); applyRemoteView(bgExecutor, inflateSynchronously, result, reInflateFlags, flag, remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, privateLayout, privateLayout.getContractedChild(), privateLayout.getVisibleWrapper( NotificationContentView.VISIBLE_TYPE_CONTRACTED), - runningInflations, applyCallback); + runningInflations, applyCallback, logger); } flag = FLAG_CONTENT_VIEW_EXPANDED; @@ -398,6 +423,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder ApplyCallback applyCallback = new ApplyCallback() { @Override public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, "expanded view applied"); result.inflatedExpandedView = v; } @@ -406,12 +432,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder return result.newExpandedView; } }; + logger.logAsyncTaskProgress(entry, "applying expanded view"); applyRemoteView(bgExecutor, inflateSynchronously, result, reInflateFlags, flag, remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, privateLayout, privateLayout.getExpandedChild(), privateLayout.getVisibleWrapper( NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations, - applyCallback); + applyCallback, logger); } } @@ -424,6 +451,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder ApplyCallback applyCallback = new ApplyCallback() { @Override public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, "heads up view applied"); result.inflatedHeadsUpView = v; } @@ -432,12 +460,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder return result.newHeadsUpView; } }; + logger.logAsyncTaskProgress(entry, "applying heads up view"); applyRemoteView(bgExecutor, inflateSynchronously, result, reInflateFlags, flag, remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, privateLayout, privateLayout.getHeadsUpChild(), privateLayout.getVisibleWrapper( VISIBLE_TYPE_HEADSUP), runningInflations, - applyCallback); + applyCallback, logger); } } @@ -449,6 +478,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder ApplyCallback applyCallback = new ApplyCallback() { @Override public void setResultView(View v) { + logger.logAsyncTaskProgress(entry, "public view applied"); result.inflatedPublicView = v; } @@ -457,19 +487,23 @@ public class NotificationContentInflater implements NotificationRowContentBinder return result.newPublicView; } }; + logger.logAsyncTaskProgress(entry, "applying public view"); applyRemoteView(bgExecutor, inflateSynchronously, result, reInflateFlags, flag, remoteViewCache, entry, row, isNewView, remoteViewClickHandler, callback, publicLayout, publicLayout.getContractedChild(), publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED), - runningInflations, applyCallback); + runningInflations, applyCallback, logger); } // Let's try to finish, maybe nobody is even inflating anything finishIfDone(result, reInflateFlags, remoteViewCache, runningInflations, callback, entry, - row); + row, logger); CancellationSignal cancellationSignal = new CancellationSignal(); cancellationSignal.setOnCancelListener( - () -> runningInflations.values().forEach(CancellationSignal::cancel)); + () -> { + logger.logAsyncTaskProgress(entry, "apply cancelled"); + runningInflations.values().forEach(CancellationSignal::cancel); + }); return cancellationSignal; } @@ -491,7 +525,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder View existingView, NotificationViewWrapper existingWrapper, final HashMap<Integer, CancellationSignal> runningInflations, - ApplyCallback applyCallback) { + ApplyCallback applyCallback, + NotificationContentInflaterLogger logger) { RemoteViews newContentView = applyCallback.getRemoteView(); if (inflateSynchronously) { try { @@ -511,7 +546,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder existingWrapper.onReinflated(); } } catch (Exception e) { - handleInflationError(runningInflations, e, row.getEntry(), callback); + handleInflationError(runningInflations, e, row.getEntry(), callback, logger, + "applying view synchronously"); // Add a running inflation to make sure we don't trigger callbacks. // Safe to do because only happens in tests. runningInflations.put(inflationId, new CancellationSignal()); @@ -532,7 +568,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder String invalidReason = isValidView(v, entry, row.getResources()); if (invalidReason != null) { handleInflationError(runningInflations, new InflationException(invalidReason), - row.getEntry(), callback); + row.getEntry(), callback, logger, "applied invalid view"); runningInflations.remove(inflationId); return; } @@ -543,7 +579,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder } runningInflations.remove(inflationId); finishIfDone(result, reInflateFlags, remoteViewCache, runningInflations, - callback, entry, row); + callback, entry, row, logger); } @Override @@ -569,7 +605,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder } catch (Exception anotherException) { runningInflations.remove(inflationId); handleInflationError(runningInflations, e, row.getEntry(), - callback); + callback, logger, "applying view"); } } }; @@ -653,8 +689,10 @@ public class NotificationContentInflater implements NotificationRowContentBinder private static void handleInflationError( HashMap<Integer, CancellationSignal> runningInflations, Exception e, - NotificationEntry notification, @Nullable InflationCallback callback) { + NotificationEntry notification, @Nullable InflationCallback callback, + NotificationContentInflaterLogger logger, String logContext) { Assert.isMainThread(); + logger.logAsyncTaskException(notification, logContext, e); runningInflations.values().forEach(CancellationSignal::cancel); if (callback != null) { callback.handleInflationException(notification, e); @@ -670,11 +708,12 @@ public class NotificationContentInflater implements NotificationRowContentBinder @InflationFlag int reInflateFlags, NotifRemoteViewCache remoteViewCache, HashMap<Integer, CancellationSignal> runningInflations, @Nullable InflationCallback endListener, NotificationEntry entry, - ExpandableNotificationRow row) { + ExpandableNotificationRow row, NotificationContentInflaterLogger logger) { Assert.isMainThread(); NotificationContentView privateLayout = row.getPrivateLayout(); NotificationContentView publicLayout = row.getPublicLayout(); if (runningInflations.isEmpty()) { + logger.logAsyncTaskProgress(entry, "finishing"); boolean setRepliesAndActions = true; if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) { if (result.inflatedContentView != null) { @@ -828,6 +867,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder private final boolean mIsMediaInQS; private final SmartReplyStateInflater mSmartRepliesInflater; private final NotifLayoutInflaterFactory.Provider mNotifLayoutInflaterFactoryProvider; + private final NotificationContentInflaterLogger mLogger; private AsyncInflationTask( Executor bgExecutor, @@ -844,7 +884,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder RemoteViews.InteractionHandler remoteViewClickHandler, boolean isMediaFlagEnabled, SmartReplyStateInflater smartRepliesInflater, - NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider) { + NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider, + NotificationContentInflaterLogger logger) { mEntry = entry; mRow = row; mBgExecutor = bgExecutor; @@ -861,6 +902,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder mConversationProcessor = conversationProcessor; mIsMediaInQS = isMediaFlagEnabled; mNotifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider; + mLogger = logger; entry.setInflationTask(this); } @@ -900,13 +942,16 @@ public class NotificationContentInflater implements NotificationRowContentBinder packageContext = new RtlEnabledContext(packageContext); } if (mEntry.getRanking().isConversation()) { - mConversationProcessor.processNotification(mEntry, recoveredBuilder); + mConversationProcessor.processNotification(mEntry, recoveredBuilder, mLogger); } InflationProgress inflationProgress = createRemoteViews(mReInflateFlags, recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, packageContext, mRow, - mNotifLayoutInflaterFactoryProvider); + mNotifLayoutInflaterFactoryProvider, mLogger); + mLogger.logAsyncTaskProgress(mEntry, + "getting existing smart reply state (on wrong thread!)"); InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState(); + mLogger.logAsyncTaskProgress(mEntry, "inflating smart reply views"); InflationProgress result = inflateSmartReplyViews( inflationProgress, mReInflateFlags, @@ -914,14 +959,20 @@ public class NotificationContentInflater implements NotificationRowContentBinder mContext, packageContext, previousSmartReplyState, - mSmartRepliesInflater); + mSmartRepliesInflater, + mLogger); + mLogger.logAsyncTaskProgress(mEntry, + "getting row image resolver (on wrong thread!)"); + final NotificationInlineImageResolver imageResolver = mRow.getImageResolver(); // wait for image resolver to finish preloading - mRow.getImageResolver().waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS); + mLogger.logAsyncTaskProgress(mEntry, "waiting for preloaded images"); + imageResolver.waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS); return result; } catch (Exception e) { mError = e; + mLogger.logAsyncTaskException(mEntry, "inflating", e); return null; } } @@ -929,6 +980,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder @Override protected void onPostExecute(InflationProgress result) { if (mError == null) { + // Logged in detail in apply. mCancellationSignal = apply( mBgExecutor, mInflateSynchronously, @@ -938,7 +990,8 @@ public class NotificationContentInflater implements NotificationRowContentBinder mEntry, mRow, mRemoteViewClickHandler, - this); + this /* callback */, + mLogger); } else { handleError(mError); } @@ -961,10 +1014,13 @@ public class NotificationContentInflater implements NotificationRowContentBinder @Override public void abort() { + mLogger.logAsyncTaskProgress(mEntry, "cancelling inflate"); cancel(true /* mayInterruptIfRunning */); if (mCancellationSignal != null) { + mLogger.logAsyncTaskProgress(mEntry, "cancelling apply"); mCancellationSignal.cancel(); } + mLogger.logAsyncTaskProgress(mEntry, "aborted"); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt new file mode 100644 index 000000000000..4f5455dc455f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterLogger.kt @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row + +import com.android.systemui.log.LogBuffer +import com.android.systemui.log.core.LogLevel +import com.android.systemui.log.dagger.NotifInflationLog +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.logKey +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag +import javax.inject.Inject + +class NotificationContentInflaterLogger +@Inject +constructor(@NotifInflationLog private val buffer: LogBuffer) { + fun logNotBindingRowWasRemoved(entry: NotificationEntry) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = entry.logKey }, + { "not inflating $str1: row was removed" } + ) + } + + fun logBinding(entry: NotificationEntry, @InflationFlag flag: Int) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + int1 = flag + }, + { "binding views ${flagToString(int1)} for $str1" } + ) + } + + fun logCancelBindAbortedTask(entry: NotificationEntry) { + buffer.log( + TAG, + LogLevel.INFO, + { str1 = entry.logKey }, + { "aborted task to cancel binding $str1" } + ) + } + + fun logUnbinding(entry: NotificationEntry, @InflationFlag flag: Int) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + int1 = flag + }, + { "unbinding views ${flagToString(int1)} for $str1" } + ) + } + + fun logAsyncTaskProgress(entry: NotificationEntry, progress: String) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = progress + }, + { "async task for $str1: $str2" } + ) + } + + fun logAsyncTaskException(entry: NotificationEntry, logContext: String, exception: Throwable) { + buffer.log( + TAG, + LogLevel.DEBUG, + { + str1 = entry.logKey + str2 = logContext + str3 = exception.stackTraceToString() + }, + { "async task for $str1 got exception $str2: $str3" } + ) + } + + companion object { + fun flagToString(@InflationFlag flag: Int): String { + if (flag == 0) { + return "NONE" + } + if (flag == FLAG_CONTENT_VIEW_ALL) { + return "ALL" + } + + var l = mutableListOf<String>() + if (flag and FLAG_CONTENT_VIEW_CONTRACTED != 0) { + l.add("CONTRACTED") + } + if (flag and FLAG_CONTENT_VIEW_EXPANDED != 0) { + l.add("EXPANDED") + } + if (flag and FLAG_CONTENT_VIEW_HEADS_UP != 0) { + l.add("HEADS_UP") + } + if (flag and FLAG_CONTENT_VIEW_PUBLIC != 0) { + l.add("PUBLIC") + } + return l.joinToString("|") + } + } +} + +private const val TAG = "NotificationContentInflater" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java index a9f83c8b9e6b..d7b7aa210257 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java @@ -54,8 +54,9 @@ public interface NotificationRowContentBinder { * * @param entry notification * @param row notification row to cancel bind on + * @return true if an on-going bind operation was cancelled */ - void cancelBind( + boolean cancelBind( @NonNull NotificationEntry entry, @NonNull ExpandableNotificationRow row); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java index 81cf14646465..b70da00ad517 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java @@ -57,7 +57,7 @@ public class RowContentBindStage extends BindStage<RowContentBindParams> { @NonNull StageCallback callback) { RowContentBindParams params = getStageParams(entry); - mLogger.logStageParams(entry, params); + mLogger.logExecutingStage(entry, params); // Resolve content to bind/unbind. @InflationFlag int inflationFlags = params.getContentViews(); @@ -96,7 +96,10 @@ public class RowContentBindStage extends BindStage<RowContentBindParams> { protected void abortStage( @NonNull NotificationEntry entry, @NonNull ExpandableNotificationRow row) { - mBinder.cancelBind(entry, row); + final boolean cancelledBind = mBinder.cancelBind(entry, row); + if (cancelledBind) { + mLogger.logAbortStageCancelledBind(entry); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt index 02627fd8f975..1b961cfbb34c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt @@ -16,22 +16,30 @@ package com.android.systemui.statusbar.notification.row -import com.android.systemui.log.dagger.NotificationLog import com.android.systemui.log.LogBuffer import com.android.systemui.log.core.LogLevel.INFO +import com.android.systemui.log.dagger.NotifInflationLog import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.logKey import javax.inject.Inject class RowContentBindStageLogger @Inject constructor( - @NotificationLog private val buffer: LogBuffer + @NotifInflationLog private val buffer: LogBuffer ) { - fun logStageParams(entry: NotificationEntry, stageParams: RowContentBindParams) { + fun logExecutingStage(entry: NotificationEntry, stageParams: RowContentBindParams) { buffer.log(TAG, INFO, { str1 = entry.logKey str2 = stageParams.toString() }, { - "Invalidated notif $str1 with params: $str2" + "executing bind stage for $str1 with params $str2" + }) + } + + fun logAbortStageCancelledBind(entry: NotificationEntry) { + buffer.log(TAG, INFO, { + str1 = entry.logKey + }, { + "cancelled bind to abort stage for $str1" }) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index 0ff1a9561748..67c0c94d6544 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -44,7 +44,6 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.qs.QSPanelController; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; -import com.android.systemui.statusbar.NotificationPresenter; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.util.Compile; @@ -183,8 +182,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { return contextForUser.getPackageManager(); } - void start(); - boolean updateIsKeyguard(); boolean updateIsKeyguard(boolean forceStateChange); @@ -200,8 +197,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { void onKeyguardViewManagerStatesUpdated(); - NotificationPresenter getPresenter(); - /** * Used to dispatch initial touch events before crossing the threshold to pull down the * notification shade. After that, since the launcher window is set to slippery, input @@ -220,8 +215,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { /** */ boolean getCommandQueuePanelsEnabled(); - BiometricUnlockController getBiometricUnlockController(); - void showWirelessChargingAnimation(int batteryLevel); void checkBarModes(); @@ -230,9 +223,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { void setInteracting(int barWindow, boolean interacting); - @Override - void dump(PrintWriter pwOriginal, String[] args); - /** @deprecated Use {@link DisplayMetricsRepository} instead. */ @Deprecated float getDisplayWidth(); @@ -281,8 +271,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { void setBouncerShowing(boolean bouncerShowing); - int getWakefulnessState(); - boolean isScreenFullyOff(); void showScreenPinningRequest(int taskId, boolean allowCancel); @@ -323,8 +311,6 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { boolean isBouncerShowingOverDream(); - boolean isKeyguardSecure(); - void updateNotificationPanelTouchState(); int getRotation(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt index 37038a357479..98ba6d91413f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt @@ -23,9 +23,7 @@ import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.navigationbar.NavigationBarView import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.qs.QSPanelController -import com.android.systemui.statusbar.NotificationPresenter import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow -import java.io.PrintWriter /** * Empty implementation of [CentralSurfaces] for variants only need to override portions of the @@ -41,15 +39,12 @@ abstract class CentralSurfacesEmptyImpl : CentralSurfaces { override fun getKeyguardMessageArea(): AuthKeyguardMessageArea? = null override fun isLaunchingActivityOverLockscreen() = false override fun onKeyguardViewManagerStatesUpdated() {} - override fun getPresenter(): NotificationPresenter? = null override fun onInputFocusTransfer(start: Boolean, cancel: Boolean, velocity: Float) {} override fun getCommandQueuePanelsEnabled() = false - override fun getBiometricUnlockController(): BiometricUnlockController? = null override fun showWirelessChargingAnimation(batteryLevel: Int) {} override fun checkBarModes() {} override fun updateBubblesVisibility() {} override fun setInteracting(barWindow: Int, interacting: Boolean) {} - override fun dump(pwOriginal: PrintWriter, args: Array<String>) {} override fun getDisplayWidth() = 0f override fun getDisplayHeight() = 0f override fun showKeyguard() {} @@ -77,7 +72,6 @@ abstract class CentralSurfacesEmptyImpl : CentralSurfaces { override fun showPinningEnterExitToast(entering: Boolean) {} override fun showPinningEscapeToast() {} override fun setBouncerShowing(bouncerShowing: Boolean) {} - override fun getWakefulnessState() = 0 override fun isScreenFullyOff() = false override fun showScreenPinningRequest(taskId: Int, allowCancel: Boolean) {} override fun getEmergencyActionIntent(): Intent? = null @@ -95,7 +89,6 @@ abstract class CentralSurfacesEmptyImpl : CentralSurfaces { override fun isBouncerShowing() = false override fun isBouncerShowingScrimmed() = false override fun isBouncerShowingOverDream() = false - override fun isKeyguardSecure() = false override fun updateNotificationPanelTouchState() {} override fun getRotation() = 0 override fun setBarStateForTest(state: Int) {} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 8cdf7d8a100d..0277a36c91ad 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -222,9 +222,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; -import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule; -import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BrightnessMirrorController; @@ -454,7 +452,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mNotificationShadeWindowViewControllerLazy; private final DozeParameters mDozeParameters; private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy; - private final CentralSurfacesComponent.Factory mCentralSurfacesComponentFactory; private final PluginManager mPluginManager; private final ShadeController mShadeController; private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor; @@ -500,8 +497,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final Provider<FingerprintManager> mFingerprintManager; private final ActivityStarter mActivityStarter; - private CentralSurfacesComponent mCentralSurfacesComponent; - /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */ private @Appearance int mAppearance; @@ -702,7 +697,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { DozeScrimController dozeScrimController, VolumeComponent volumeComponent, CommandQueue commandQueue, - CentralSurfacesComponent.Factory centralSurfacesComponentFactory, Lazy<CentralSurfacesCommandQueueCallbacks> commandQueueCallbacksLazy, PluginManager pluginManager, ShadeController shadeController, @@ -813,7 +807,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy; mVolumeComponent = volumeComponent; mCommandQueue = commandQueue; - mCentralSurfacesComponentFactory = centralSurfacesComponentFactory; mCommandQueueCallbacksLazy = commandQueueCallbacksLazy; mPluginManager = pluginManager; mShadeController = shadeController; @@ -1193,10 +1186,15 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { updateResources(); updateTheme(); - inflateStatusBarWindow(); + setUpShade(); getNotificationShadeWindowView().setOnTouchListener(getStatusBarWindowTouchListener()); mWallpaperController.setRootView(getNotificationShadeWindowView()); + mDemoModeController.addCallback(mDemoModeCallback); + + mCommandQueueCallbacks = mCommandQueueCallbacksLazy.get(); + mCommandQueue.addCallback(mCommandQueueCallbacks); + // TODO: Deal with the ugliness that comes from having some of the status bar broken out // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot. if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) { @@ -1227,8 +1225,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { setBouncerShowingForStatusBarComponents(mBouncerShowing); checkBarModes(); }); - mStatusBarInitializer.initializeStatusBar( - mCentralSurfacesComponent::createCollapsedStatusBarFragment); + mStatusBarInitializer.initializeStatusBar(); mStatusBarTouchableRegionManager.setup(this, getNotificationShadeWindowView()); @@ -1551,15 +1548,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { }; } - private void inflateStatusBarWindow() { - if (mCentralSurfacesComponent != null) { - Log.e(TAG, "CentralSurfacesComponent being recreated; this is unexpected."); - } - mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create(); - mFragmentService.addFragmentInstantiationProvider( - CollapsedStatusBarFragment.class, - mCentralSurfacesComponent::createCollapsedStatusBarFragment); - + private void setUpShade() { // Ideally, NotificationShadeWindowController could automatically fetch the window root view // in #attach or a CoreStartable.start method or something similar. But for now, to avoid // regressions, we'll continue standing up the root view in CentralSurfaces. @@ -1568,12 +1557,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mShadeController.setNotificationShadeWindowViewController( getNotificationShadeWindowViewController()); mBackActionInteractor.setup(mQsController, mShadeSurface); - - // Listen for demo mode changes - mDemoModeController.addCallback(mDemoModeCallback); - - mCommandQueueCallbacks = mCommandQueueCallbacksLazy.get(); - mCommandQueue.addCallback(mCommandQueueCallbacks); } protected NotificationShadeWindowViewController getNotificationShadeWindowViewController() { @@ -1666,11 +1649,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { logStateToEventlog(); } - @Override - public NotificationPresenter getPresenter() { - return mPresenter; - } - @VisibleForTesting @Override public void setBarStateForTest(int state) { @@ -1745,11 +1723,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } @Override - public BiometricUnlockController getBiometricUnlockController() { - return mBiometricUnlockController; - } - - @Override public void showTransientUnchecked() { if (!mTransientShown) { mTransientShown = true; @@ -2503,7 +2476,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mStatusBarKeyguardViewManager.reset(true); } else if (mState == StatusBarState.KEYGUARD && !mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing() - && isKeyguardSecure()) { + && mStatusBarKeyguardViewManager.isSecure()) { mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); } } @@ -2842,11 +2815,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { } }; - @Override - public int getWakefulnessState() { - return mWakefulnessLifecycle.getWakefulness(); - } - /** * @return true if the screen is currently fully off, i.e. has finished turning off and has * since not started turning on. @@ -2912,7 +2880,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { if (mDevicePolicyManager.getCameraDisabled(null, mLockscreenUserManager.getCurrentUserId())) { return false; - } else if (isKeyguardShowing() && isKeyguardSecure()) { + } else if (isKeyguardShowing() && mStatusBarKeyguardViewManager.isSecure()) { // Check if the admin has disabled the camera specifically for the keyguard return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mLockscreenUserManager.getCurrentUserId()) @@ -3215,11 +3183,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { return mBouncerShowingOverDream; } - @Override - public boolean isKeyguardSecure() { - return mStatusBarKeyguardViewManager.isSecure(); - } - // End Extra BaseStatusBarMethods. boolean isTransientShown() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index b0f8276e460d..40432eee95bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -1480,7 +1480,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump public void setScrimBehindChangeRunnable(Runnable changeRunnable) { // TODO: remove this. This is necessary because of an order-of-operations limitation. - // The fix is to move more of these class into @CentralSurfacesScope + // The fix is to move more of these class into @SysUISingleton. if (mScrimBehind == null) { mScrimBehindChangeRunnable = changeRunnable; } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index 37f032b464b7..2c15e27b8148 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -125,6 +125,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( // FrameCallback used to delay starting the light reveal animation until the next frame private val startLightRevealCallback = TraceUtils.namedRunnable("startLightReveal") { + lightRevealAnimationPlaying = true lightRevealAnimator.start() } @@ -268,7 +269,6 @@ class UnlockedScreenOffAnimationController @Inject constructor( decidedToAnimateGoingToSleep = true shouldAnimateInKeyguard = true - lightRevealAnimationPlaying = true // Start the animation on the next frame. startAnimation() is called after // PhoneWindowManager makes a binder call to System UI on @@ -283,7 +283,8 @@ class UnlockedScreenOffAnimationController @Inject constructor( // dispatched, a race condition could make it possible for this callback to be run // as the device is waking up. That results in the AOD UI being shown while we wake // up, with unpredictable consequences. - if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY)) { + if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY) && + shouldAnimateInKeyguard) { aodUiAnimationPlaying = true // Show AOD. That'll cause the KeyguardVisibilityHelper to call diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java deleted file mode 100644 index 1a04b913f3e6..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.phone.dagger; - -import static com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.STATUS_BAR_FRAGMENT; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import com.android.systemui.shade.ShadeHeaderController; -import com.android.systemui.statusbar.phone.CentralSurfacesImpl; -import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; - -import dagger.Subcomponent; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; - -import javax.inject.Named; -import javax.inject.Scope; - -/** - * Dagger subcomponent for classes (semi-)related to the status bar. The component is created once - * inside {@link CentralSurfacesImpl} and never re-created. - * - * TODO(b/197137564): This should likely be re-factored a bit. It includes classes that aren't - * directly related to status bar functionality, like multiple notification classes. And, the fact - * that it has many getter methods indicates that we need to access many of these classes from - * outside the component. Should more items be moved *into* this component to avoid so many getters? - */ -@Subcomponent(modules = { - StatusBarViewModule.class, -}) -@CentralSurfacesComponent.CentralSurfacesScope -public interface CentralSurfacesComponent { - /** - * Builder for {@link CentralSurfacesComponent}. - */ - @Subcomponent.Factory - interface Factory { - CentralSurfacesComponent create(); - } - - /** - * Scope annotation for singleton items within the CentralSurfacesComponent. - */ - @Documented - @Retention(RUNTIME) - @Scope - @interface CentralSurfacesScope {} - - /** - * Creates a {@link ShadeHeaderController}. - */ - ShadeHeaderController getLargeScreenShadeHeaderController(); - - /** - * Creates a new {@link CollapsedStatusBarFragment} each time it's called. See - * {@link StatusBarViewModule#createCollapsedStatusBarFragment}. - */ - @Named(STATUS_BAR_FRAGMENT) - CollapsedStatusBarFragment createCollapsedStatusBarFragment(); -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java deleted file mode 100644 index ebdde78e4ea4..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.phone.dagger; - -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.flags.FeatureFlags; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shade.ShadeExpansionStateManager; -import com.android.systemui.shade.ShadeViewController; -import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.OperatorNameViewController; -import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler; -import com.android.systemui.statusbar.phone.NotificationIconAreaController; -import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager; -import com.android.systemui.statusbar.phone.StatusBarIconController; -import com.android.systemui.statusbar.phone.StatusBarLocationPublisher; -import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; -import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger; -import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent; -import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; -import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder; -import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.statusbar.window.StatusBarWindowStateController; -import com.android.systemui.util.CarrierConfigTracker; -import com.android.systemui.util.settings.SecureSettings; - -import dagger.Module; -import dagger.Provides; - -import java.util.concurrent.Executor; - -import javax.inject.Named; - -/** - * A module for {@link CentralSurfacesComponent.CentralSurfacesScope} components. - * - * @deprecated CentralSurfacesScope will be removed shortly (b/277762009). Classes should be - * annotated with @SysUISingleton instead. - */ -@Module(subcomponents = StatusBarFragmentComponent.class) -@Deprecated -public abstract class StatusBarViewModule { - - public static final String STATUS_BAR_FRAGMENT = "status_bar_fragment"; - - /** - * Creates a new {@link CollapsedStatusBarFragment}. - * - * **IMPORTANT**: This method intentionally does not have - * {@link CentralSurfacesComponent.CentralSurfacesScope}, which means a new fragment *will* be - * created each time this method is called. This is intentional because we need fragments to - * re-created in certain lifecycle scenarios. - * - * This provider is {@link Named} such that it does not conflict with the provider inside of - * {@link StatusBarFragmentComponent}. - */ - @Provides - @Named(STATUS_BAR_FRAGMENT) - public static CollapsedStatusBarFragment createCollapsedStatusBarFragment( - StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory, - OngoingCallController ongoingCallController, - SystemStatusAnimationScheduler animationScheduler, - StatusBarLocationPublisher locationPublisher, - NotificationIconAreaController notificationIconAreaController, - ShadeExpansionStateManager shadeExpansionStateManager, - FeatureFlags featureFlags, - StatusBarIconController statusBarIconController, - StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory, - CollapsedStatusBarViewModel collapsedStatusBarViewModel, - CollapsedStatusBarViewBinder collapsedStatusBarViewBinder, - StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager, - KeyguardStateController keyguardStateController, - ShadeViewController shadeViewController, - StatusBarStateController statusBarStateController, - CommandQueue commandQueue, - CarrierConfigTracker carrierConfigTracker, - CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger, - OperatorNameViewController.Factory operatorNameViewControllerFactory, - SecureSettings secureSettings, - @Main Executor mainExecutor, - DumpManager dumpManager, - StatusBarWindowStateController statusBarWindowStateController, - KeyguardUpdateMonitor keyguardUpdateMonitor - ) { - return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory, - ongoingCallController, - animationScheduler, - locationPublisher, - notificationIconAreaController, - shadeExpansionStateManager, - featureFlags, - statusBarIconController, - darkIconManagerFactory, - collapsedStatusBarViewModel, - collapsedStatusBarViewBinder, - statusBarHideIconsForBouncerManager, - keyguardStateController, - shadeViewController, - statusBarStateController, - commandQueue, - carrierConfigTracker, - collapsedStatusBarFragmentLogger, - operatorNameViewControllerFactory, - secureSettings, - mainExecutor, - dumpManager, - statusBarWindowStateController, - keyguardUpdateMonitor); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index 2efdf8a0b181..66f0f597ea6e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -29,7 +29,6 @@ import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.ViewStub; import android.widget.LinearLayout; import androidx.annotation.VisibleForTesting; @@ -85,6 +84,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; +import javax.inject.Inject; + /** * Contains the collapsed status bar and handles hiding/showing based on disable flags * and keyguard state. Also manages lifecycle to make sure the views it contains are being @@ -203,7 +204,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue mTransitionFromLockscreenToDreamStarted = false; }; - @SuppressLint("ValidFragment") + @Inject public CollapsedStatusBarFragment( StatusBarFragmentComponent.Factory statusBarFragmentComponentFactory, OngoingCallController ongoingCallController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentStartable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentStartable.kt new file mode 100644 index 000000000000..55af0e3d65a3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentStartable.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone.fragment + +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.fragments.FragmentService +import com.android.systemui.qs.QSFragmentStartable +import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent +import dagger.Binds +import dagger.Module +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap +import javax.inject.Inject +import javax.inject.Provider + +/** + * Provides [FragmentService] with a way to automatically inflate [CollapsedStatusBarFragment], + * similar to [QSFragmentStartable]. + */ +@SysUISingleton +class CollapsedStatusBarFragmentStartable +@Inject +constructor( + private val fragmentService: FragmentService, + private val collapsedstatusBarFragmentProvider: Provider<CollapsedStatusBarFragment> +) : CoreStartable { + override fun start() { + fragmentService.addFragmentInstantiationProvider( + CollapsedStatusBarFragment::class.java, + collapsedstatusBarFragmentProvider, + ) + } +} + +@Module(subcomponents = [StatusBarFragmentComponent::class]) +interface CollapsedStatusBarFragmentStartableModule { + @Binds + @IntoMap + @ClassKey(CollapsedStatusBarFragmentStartable::class) + fun bindsCollapsedStatusBarFragmentStartable( + startable: CollapsedStatusBarFragmentStartable + ): CoreStartable +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index c91313ad09b5..6afa5256523c 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -126,12 +126,14 @@ class ClockEventControllerTest : SysuiTestCase() { withDeps.featureFlags.apply { set(Flags.REGION_SAMPLING, false) set(Flags.DOZING_MIGRATION_1, false) + set(Flags.FACE_AUTH_REFACTOR, false) } underTest = ClockEventController( withDeps.keyguardInteractor, KeyguardTransitionInteractorFactory.create( scope = TestScope().backgroundScope, + featureFlags = withDeps.featureFlags, ) .keyguardTransitionInteractor, broadcastDispatcher, diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index e56b5c7406b6..e01b5afefe0a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -106,7 +106,6 @@ import com.android.systemui.statusbar.phone.SystemUIDialogManager; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.util.concurrency.Execution; import com.android.systemui.util.concurrency.FakeExecution; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.settings.SecureSettings; @@ -252,7 +251,9 @@ public class UdfpsControllerTest extends SysuiTestCase { @Before public void setUp() { - Execution execution = new FakeExecution(); + mContext.getOrCreateTestableResources() + .addOverride(com.android.internal.R.bool.config_ignoreUdfpsVote, false); + mUdfpsUtils = new UdfpsUtils(); when(mLayoutInflater.inflate(R.layout.udfps_view, null, false)) diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt index 3df9cbb29e4a..7fa828fbfadd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt @@ -9,6 +9,7 @@ import android.os.UserHandle import android.os.UserManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.coroutines.collectLastValue @@ -39,6 +40,7 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest +@RoboPilotTest @RunWith(AndroidJUnit4::class) class CommunalWidgetRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var appWidgetManager: AppWidgetManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt index 4ad9549d1d4a..be9f6ca0fc33 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt @@ -1,10 +1,11 @@ package com.android.systemui.communal.ui.view.layout.blueprints -import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.communal.ui.view.layout.sections.DefaultCommunalWidgetSection import org.junit.Before @@ -14,7 +15,8 @@ import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RunWith(AndroidTestingRunner::class) +@RoboPilotTest +@RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest class DefaultCommunalBlueprintTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt index 57307fc84b1c..781ad6b10b70 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt @@ -3,9 +3,10 @@ package com.android.systemui.dreams import android.animation.Animator import android.animation.AnimatorSet import android.animation.ValueAnimator -import android.testing.AndroidTestingRunner import android.view.View +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.complication.ComplicationHostViewController import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel @@ -29,8 +30,9 @@ import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class DreamOverlayAnimationsControllerTest : SysuiTestCase() { companion object { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt index 9f534ef14f54..21192fa11da3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt @@ -15,8 +15,9 @@ */ package com.android.systemui.dreams -import android.testing.AndroidTestingRunner +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -29,8 +30,9 @@ import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class DreamOverlayCallbackControllerTest : SysuiTestCase() { @Mock private lateinit var callback: DreamOverlayCallbackController.Callback diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java index 8786520ccf0e..7c36642f5417 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java @@ -28,21 +28,22 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.graphics.Region; import android.os.Handler; -import android.testing.AndroidTestingRunner; import android.view.AttachedSurfaceControl; import android.view.ViewGroup; import android.view.ViewRootImpl; import android.view.ViewTreeObserver; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.dream.lowlight.LowLightTransitionCoordinator; import com.android.keyguard.BouncerPanelExpansionCalculator; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; -import com.android.systemui.complication.ComplicationHostViewController; -import com.android.systemui.dreams.touch.scrim.BouncerlessScrimController; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; +import com.android.systemui.complication.ComplicationHostViewController; +import com.android.systemui.dreams.touch.scrim.BouncerlessScrimController; import com.android.systemui.statusbar.BlurUtils; import org.junit.Before; @@ -52,8 +53,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayContainerViewControllerTest extends SysuiTestCase { private static final int MAX_BURN_IN_OFFSET = 20; private static final long BURN_IN_PROTECTION_UPDATE_INTERVAL = 10; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java index 25d4c472dc63..be7638ef31e6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java @@ -22,10 +22,11 @@ import static org.mockito.Mockito.when; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; -import android.testing.AndroidTestingRunner; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; @@ -37,8 +38,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayNotificationCountProviderTest extends SysuiTestCase { @Mock NotificationListener mNotificationListener; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java index d99f0da494fd..8379f73402cf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java @@ -37,7 +37,6 @@ import android.service.dreams.IDreamOverlay; import android.service.dreams.IDreamOverlayCallback; import android.service.dreams.IDreamOverlayClient; import android.service.dreams.IDreamOverlayClientCallback; -import android.testing.AndroidTestingRunner; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -45,10 +44,12 @@ import android.view.WindowManagerImpl; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.ComplicationLayoutEngine; import com.android.systemui.dreams.complication.HideComplicationTouchHandler; @@ -71,8 +72,9 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayServiceTest extends SysuiTestCase { private static final ComponentName LOW_LIGHT_COMPONENT = new ComponentName("package", "lowlight"); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java index 44a78ac3bc96..2ef227c245c3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java @@ -26,10 +26,10 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.testing.AndroidTestingRunner; - +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.Complication; import com.android.systemui.flags.FeatureFlags; @@ -48,8 +48,9 @@ import org.mockito.MockitoAnnotations; import java.util.Collection; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayStateControllerTest extends SysuiTestCase { @Mock DreamOverlayStateController.Callback mCallback; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java index a78886f8d504..12cb332c7cc5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java @@ -21,10 +21,10 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.testing.AndroidTestingRunner; - +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import org.junit.Before; @@ -36,8 +36,9 @@ import org.mockito.MockitoAnnotations; import java.util.List; import java.util.concurrent.Executor; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayStatusBarItemsProviderTest extends SysuiTestCase { @Mock DreamOverlayStatusBarItemsProvider.Callback mCallback; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java index 4e74f451932b..af2dab599a66 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java @@ -41,12 +41,13 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.provider.Settings; -import android.testing.AndroidTestingRunner; import android.view.View; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.systemui.R; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.FakeLogBuffer; @@ -71,8 +72,9 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { private static final String NOTIFICATION_INDICATOR_FORMATTER_STRING = "{count, plural, =1 {# notification} other {# notifications}}"; @@ -92,8 +94,6 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { @Mock AlarmManager mAlarmManager; @Mock - AlarmManager.AlarmClockInfo mAlarmClockInfo; - @Mock NextAlarmController mNextAlarmController; @Mock DateFormatUtil mDateFormatUtil; @@ -203,8 +203,9 @@ public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { @Test public void testOnViewAttachedShowsAlarmIconWhenAlarmExists() { - when(mAlarmClockInfo.getTriggerTime()).thenReturn(1L); - when(mAlarmManager.getNextAlarmClock(anyInt())).thenReturn(mAlarmClockInfo); + final AlarmManager.AlarmClockInfo alarmClockInfo = + new AlarmManager.AlarmClockInfo(1L, null); + when(mAlarmManager.getNextAlarmClock(anyInt())).thenReturn(alarmClockInfo); mController.onViewAttached(); verify(mView).showIcon( eq(DreamOverlayStatusBarView.STATUS_ICON_ALARM_SET), eq(true), any()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java index eed4dbcb7773..d32788df30be 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java @@ -23,13 +23,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.os.Handler; -import android.testing.AndroidTestingRunner; import android.view.MotionEvent; import android.view.View; import androidx.concurrent.futures.CallbackToFutureAdapter; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.Complication; import com.android.systemui.dreams.DreamOverlayStateController; @@ -48,8 +49,9 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class HideComplicationTouchHandlerTest extends SysuiTestCase { private static final int RESTORE_TIMEOUT = 1000; private static final int HIDE_DELAY = 500; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java index 6a178895839b..4a7700fe1ca2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java @@ -23,10 +23,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.testing.AndroidTestingRunner; - +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener; @@ -41,8 +41,9 @@ import org.mockito.MockitoAnnotations; import kotlinx.coroutines.CoroutineScope; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class AssistantAttentionConditionTest extends SysuiTestCase { @Mock Condition.Callback mCallback; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java index 68c79652ac00..cd2efded7e85 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java @@ -25,12 +25,13 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.DreamManager; -import android.testing.AndroidTestingRunner; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shared.condition.Condition; @@ -43,8 +44,9 @@ import org.mockito.MockitoAnnotations; import kotlinx.coroutines.CoroutineScope; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class DreamConditionTest extends SysuiTestCase { @Mock Condition.Callback mCallback; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java index 3f9b198ee17d..90076fd21520 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java @@ -31,16 +31,17 @@ import android.animation.ValueAnimator; import android.content.pm.UserInfo; import android.graphics.Rect; import android.graphics.Region; -import android.testing.AndroidTestingRunner; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.VelocityTracker; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dreams.touch.scrim.ScrimController; @@ -56,6 +57,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; @@ -63,8 +65,9 @@ import org.mockito.MockitoAnnotations; import java.util.Collections; import java.util.Optional; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { @Mock CentralSurfaces mCentralSurfaces; @@ -107,6 +110,12 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { @Mock LockPatternUtils mLockPatternUtils; + @Mock + Region mRegion; + + @Captor + ArgumentCaptor<Rect> mRectCaptor; + FakeUserTracker mUserTracker; private static final float TOUCH_REGION = .3f; @@ -153,10 +162,10 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { */ @Test public void testSessionStart() { - final Region region = Region.obtain(); - mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, region); + mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion); - final Rect bounds = region.getBounds(); + verify(mRegion).op(mRectCaptor.capture(), eq(Region.Op.UNION)); + final Rect bounds = mRectCaptor.getValue(); final Rect expected = new Rect(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java index 2b9821406fea..ff6d97d3b380 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java @@ -21,12 +21,13 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.testing.AndroidTestingRunner; import android.view.GestureDetector; import android.view.MotionEvent; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shared.system.InputChannelCompat; @@ -42,8 +43,9 @@ import org.mockito.MockitoAnnotations; import java.util.Optional; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class ShadeTouchHandlerTest extends SysuiTestCase { @Mock CentralSurfaces mCentralSurfaces; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java index 79c535aea2d0..da393818c6f7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java @@ -22,10 +22,11 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import android.os.PowerManager; -import android.testing.AndroidTestingRunner; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.util.concurrency.FakeExecutor; @@ -37,8 +38,9 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class BouncerlessScrimControllerTest extends SysuiTestCase { @Mock BouncerlessScrimController.Callback mCallback; diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java index ac9822db85d6..81f6fe3e24d3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java @@ -22,10 +22,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.testing.AndroidTestingRunner; - +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; @@ -38,8 +38,9 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +@RoboPilotTest @SmallTest -@RunWith(AndroidTestingRunner.class) +@RunWith(AndroidJUnit4.class) public class ScrimManagerTest extends SysuiTestCase { @Mock ScrimController mBouncerlessScrimController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt index 36822e6a4e24..e2362f64b885 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt @@ -63,6 +63,7 @@ import com.android.systemui.util.mockito.whenever import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -174,12 +175,17 @@ class CustomizationProviderTest : SysuiTestCase() { set(Flags.REVAMPED_WALLPAPER_UI, true) set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true) set(Flags.FACE_AUTH_REFACTOR, true) + set(Flags.SCENE_CONTAINER, false) } underTest.interactor = KeyguardQuickAffordanceInteractor( keyguardInteractor = KeyguardInteractorFactory.create( featureFlags = featureFlags, + sceneInteractor = + mock { + whenever(transitioningTo).thenReturn(MutableStateFlow(null)) + }, ) .keyguardInteractor, lockPatternUtils = lockPatternUtils, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt index 972af4a8a172..ce280d7b221b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt @@ -15,6 +15,8 @@ * */ +@file:OptIn(ExperimentalCoroutinesApi::class) + package com.android.systemui.keyguard.domain.interactor import android.app.StatusBarManager @@ -27,11 +29,19 @@ import com.android.systemui.common.ui.data.repository.FakeConfigurationRepositor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR +import com.android.systemui.flags.Flags.SCENE_CONTAINER import com.android.systemui.keyguard.data.repository.FakeCommandQueue import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel +import com.android.systemui.scene.SceneTestUtils +import com.android.systemui.scene.domain.interactor.SceneInteractor +import com.android.systemui.scene.shared.model.ObservableTransitionState +import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.data.repository.FakeShadeRepository import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent @@ -54,25 +64,36 @@ class KeyguardInteractorTest : SysuiTestCase() { private lateinit var bouncerRepository: FakeKeyguardBouncerRepository private lateinit var configurationRepository: FakeConfigurationRepository private lateinit var shadeRepository: FakeShadeRepository + private lateinit var sceneInteractor: SceneInteractor + private lateinit var transitionState: MutableStateFlow<ObservableTransitionState> @Before fun setUp() { MockitoAnnotations.initMocks(this) - featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } + featureFlags = + FakeFeatureFlags().apply { + set(FACE_AUTH_REFACTOR, true) + set(SCENE_CONTAINER, true) + } commandQueue = FakeCommandQueue() - testScope = TestScope() - repository = FakeKeyguardRepository() + val sceneTestUtils = SceneTestUtils(this) + testScope = sceneTestUtils.testScope + repository = sceneTestUtils.keyguardRepository bouncerRepository = FakeKeyguardBouncerRepository() configurationRepository = FakeConfigurationRepository() shadeRepository = FakeShadeRepository() + sceneInteractor = sceneTestUtils.sceneInteractor() + transitionState = MutableStateFlow(ObservableTransitionState.Idle(SceneKey.Gone)) + sceneInteractor.setTransitionState(transitionState) underTest = KeyguardInteractor( - repository, - commandQueue, - featureFlags, - bouncerRepository, - configurationRepository, - shadeRepository, + repository = repository, + commandQueue = commandQueue, + featureFlags = featureFlags, + bouncerRepository = bouncerRepository, + configurationRepository = configurationRepository, + shadeRepository = shadeRepository, + sceneInteractorProvider = { sceneInteractor }, ) } @@ -180,4 +201,28 @@ class KeyguardInteractorTest : SysuiTestCase() { assertThat(secureCameraActive()).isFalse() } + + @Test + fun animationDozingTransitions() = + testScope.runTest { + val isAnimate by collectLastValue(underTest.animateDozingTransitions) + + underTest.setAnimateDozingTransitions(true) + runCurrent() + assertThat(isAnimate).isTrue() + + underTest.setAnimateDozingTransitions(false) + runCurrent() + assertThat(isAnimate).isFalse() + + underTest.setAnimateDozingTransitions(true) + transitionState.value = + ObservableTransitionState.Transition( + fromScene = SceneKey.Gone, + toScene = SceneKey.Lockscreen, + progress = flowOf(0f), + ) + runCurrent() + assertThat(isAnimate).isFalse() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt index f24ea6c0216f..499a6362ce05 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/OccludingAppDeviceEntryInteractorTest.kt @@ -52,6 +52,7 @@ import com.android.systemui.util.mockito.whenever import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -103,6 +104,7 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, false) set(Flags.DELAY_BOUNCER, false) + set(Flags.SCENE_CONTAINER, false) } trustRepository = FakeTrustRepository() powerRepository = FakePowerRepository() @@ -121,6 +123,8 @@ class OccludingAppDeviceEntryInteractorTest : SysuiTestCase() { repository = keyguardRepository, bouncerRepository = bouncerRepository, configurationRepository = configurationRepository, + sceneInteractor = + mock { whenever(transitioningTo).thenReturn(MutableStateFlow(null)) }, ) .keyguardInteractor, PrimaryBouncerInteractor( diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt index 3576ec9601e3..7fecfc234392 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt @@ -57,11 +57,12 @@ import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth +import kotlin.math.max +import kotlin.math.min import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import org.junit.Assert.* import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -70,8 +71,6 @@ import org.mockito.ArgumentMatchers import org.mockito.Mock import org.mockito.Mockito import org.mockito.MockitoAnnotations -import kotlin.math.max -import kotlin.math.min @SmallTest @RunWith(JUnit4::class) @@ -105,9 +104,11 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { overrideResource( R.array.config_keyguardQuickAffordanceDefaults, arrayOf( - KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START + ":" + + KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START + + ":" + BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS, - KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END + ":" + + KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END + + ":" + BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET ) ) @@ -128,6 +129,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { set(Flags.FACE_AUTH_REFACTOR, true) set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, false) set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, false) + set(Flags.SCENE_CONTAINER, false) } val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags) @@ -144,16 +146,16 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { KeyguardQuickAffordanceLocalUserSelectionManager( context = context, userFileManager = - mock<UserFileManager>().apply { - whenever( - getSharedPreferences( - ArgumentMatchers.anyString(), - ArgumentMatchers.anyInt(), - ArgumentMatchers.anyInt(), - ) - ) - .thenReturn(FakeSharedPreferences()) - }, + mock<UserFileManager>().apply { + whenever( + getSharedPreferences( + ArgumentMatchers.anyString(), + ArgumentMatchers.anyInt(), + ArgumentMatchers.anyInt(), + ) + ) + .thenReturn(FakeSharedPreferences()) + }, userTracker = userTracker, broadcastDispatcher = fakeBroadcastDispatcher, ) @@ -172,42 +174,43 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { remoteUserSelectionManager = remoteUserSelectionManager, userTracker = userTracker, legacySettingSyncer = - KeyguardQuickAffordanceLegacySettingSyncer( - scope = testScope.backgroundScope, - backgroundDispatcher = testDispatcher, - secureSettings = FakeSettings(), - selectionsManager = localUserSelectionManager, - ), + KeyguardQuickAffordanceLegacySettingSyncer( + scope = testScope.backgroundScope, + backgroundDispatcher = testDispatcher, + secureSettings = FakeSettings(), + selectionsManager = localUserSelectionManager, + ), configs = - setOf( - homeControlsQuickAffordanceConfig, - quickAccessWalletAffordanceConfig, - qrCodeScannerAffordanceConfig, - ), + setOf( + homeControlsQuickAffordanceConfig, + quickAccessWalletAffordanceConfig, + qrCodeScannerAffordanceConfig, + ), dumpManager = mock(), userHandle = UserHandle.SYSTEM, ) - underTest = KeyguardQuickAffordancesCombinedViewModel( - quickAffordanceInteractor = - KeyguardQuickAffordanceInteractor( - keyguardInteractor = keyguardInteractor, - lockPatternUtils = lockPatternUtils, - keyguardStateController = keyguardStateController, - userTracker = userTracker, - activityStarter = activityStarter, - featureFlags = featureFlags, - repository = { quickAffordanceRepository }, - launchAnimator = launchAnimator, - logger = logger, - devicePolicyManager = devicePolicyManager, - dockManager = dockManager, - biometricSettingsRepository = biometricSettingsRepository, - backgroundDispatcher = testDispatcher, - appContext = mContext, - ), - keyguardInteractor = keyguardInteractor - ) + underTest = + KeyguardQuickAffordancesCombinedViewModel( + quickAffordanceInteractor = + KeyguardQuickAffordanceInteractor( + keyguardInteractor = keyguardInteractor, + lockPatternUtils = lockPatternUtils, + keyguardStateController = keyguardStateController, + userTracker = userTracker, + activityStarter = activityStarter, + featureFlags = featureFlags, + repository = { quickAffordanceRepository }, + launchAnimator = launchAnimator, + logger = logger, + devicePolicyManager = devicePolicyManager, + dockManager = dockManager, + biometricSettingsRepository = biometricSettingsRepository, + backgroundDispatcher = testDispatcher, + appContext = mContext, + ), + keyguardInteractor = keyguardInteractor + ) } @Test @@ -242,9 +245,8 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Test fun startButton_hiddenWhenDevicePolicyDisablesAllKeyguardFeatures() = testScope.runTest { - whenever( - devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId) - ).thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) + whenever(devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId)) + .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) repository.setKeyguardShowing(true) val latest by collectLastValue(underTest.startButton) @@ -267,10 +269,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { assertQuickAffordanceViewModel( viewModel = latest, testConfig = - TestConfig( - isVisible = false, - slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), - ), + TestConfig( + isVisible = false, + slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), + ), configKey = configKey, ) } @@ -278,9 +280,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Test fun startButton_inPreviewMode_visibleEvenWhenKeyguardNotShowing() = testScope.runTest { - underTest.onPreviewSlotSelected( - KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START - ) + underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START) underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true) repository.setKeyguardShowing(false) @@ -291,30 +291,30 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { setUpQuickAffordanceModel( position = KeyguardQuickAffordancePosition.BOTTOM_START, testConfig = + TestConfig( + isVisible = true, + isClickable = true, + isActivated = true, + icon = icon, + canShowWhileLocked = false, + intent = Intent("action"), + slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), + ), + ) + + assertQuickAffordanceViewModel( + viewModel = latest(), + testConfig = TestConfig( isVisible = true, - isClickable = true, - isActivated = true, + isClickable = false, + isActivated = false, icon = icon, canShowWhileLocked = false, intent = Intent("action"), + isSelected = true, slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), ), - ) - - assertQuickAffordanceViewModel( - viewModel = latest(), - testConfig = - TestConfig( - isVisible = true, - isClickable = false, - isActivated = false, - icon = icon, - canShowWhileLocked = false, - intent = Intent("action"), - isSelected = true, - slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), - ), configKey = configKey, ) Truth.assertThat(latest()?.isSelected).isTrue() @@ -323,9 +323,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { @Test fun endButton_inHiglightedPreviewMode_dimmedWhenOtherIsSelected() = testScope.runTest { - underTest.onPreviewSlotSelected( - KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START - ) + underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START) underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true) repository.setKeyguardShowing(false) @@ -335,20 +333,6 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { setUpQuickAffordanceModel( position = KeyguardQuickAffordancePosition.BOTTOM_START, testConfig = - TestConfig( - isVisible = true, - isClickable = true, - isActivated = true, - icon = icon, - canShowWhileLocked = false, - intent = Intent("action"), - slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), - ), - ) - val configKey = - setUpQuickAffordanceModel( - position = KeyguardQuickAffordancePosition.BOTTOM_END, - testConfig = TestConfig( isVisible = true, isClickable = true, @@ -356,23 +340,37 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { icon = icon, canShowWhileLocked = false, intent = Intent("action"), - slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(), + slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(), ), + ) + val configKey = + setUpQuickAffordanceModel( + position = KeyguardQuickAffordancePosition.BOTTOM_END, + testConfig = + TestConfig( + isVisible = true, + isClickable = true, + isActivated = true, + icon = icon, + canShowWhileLocked = false, + intent = Intent("action"), + slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(), + ), ) assertQuickAffordanceViewModel( viewModel = endButton(), testConfig = - TestConfig( - isVisible = true, - isClickable = false, - isActivated = false, - icon = icon, - canShowWhileLocked = false, - intent = Intent("action"), - isDimmed = true, - slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(), - ), + TestConfig( + isVisible = true, + isClickable = false, + isActivated = false, + icon = icon, + canShowWhileLocked = false, + intent = Intent("action"), + isDimmed = true, + slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(), + ), configKey = configKey, ) } @@ -390,7 +388,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { icon = mock(), canShowWhileLocked = false, intent = - null, // This will cause it to tell the system that the click was handled. + null, // This will cause it to tell the system that the click was handled. slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(), ) val configKey = @@ -610,10 +608,10 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { KeyguardQuickAffordanceConfig.LockScreenState.Visible( icon = testConfig.icon ?: error("Icon is unexpectedly null!"), activationState = - when (testConfig.isActivated) { - true -> ActivationState.Active - false -> ActivationState.Inactive - } + when (testConfig.isActivated) { + true -> ActivationState.Active + false -> ActivationState.Inactive + } ) } else { KeyguardQuickAffordanceConfig.LockScreenState.Hidden @@ -644,9 +642,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { ) ) if (testConfig.intent != null) { - Truth.assertThat( - Mockito.mockingDetails(activityStarter).invocations - ).hasSize(1) + Truth.assertThat(Mockito.mockingDetails(activityStarter).invocations).hasSize(1) } else { Mockito.verifyZeroInteractions(activityStarter) } @@ -670,4 +666,4 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() { check(!isVisible || icon != null) { "Must supply non-null icon if visible!" } } } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt new file mode 100644 index 000000000000..49f536e26ce6 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.media.controls.ui + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.MotionEvent +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.media.controls.util.MediaUiEventLogger +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.qs.PageIndicator +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.eq +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@TestableLooper.RunWithLooper(setAsMainLooper = true) +@RunWith(AndroidTestingRunner::class) +class MediaCarouselScrollHandlerTest : SysuiTestCase() { + + private val carouselWidth = 1038 + private val motionEventUp = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0f, 0f, 0) + + @Mock lateinit var mediaCarousel: MediaScrollView + @Mock lateinit var pageIndicator: PageIndicator + @Mock lateinit var dismissCallback: () -> Unit + @Mock lateinit var translationChangedListener: () -> Unit + @Mock lateinit var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit + @Mock lateinit var closeGuts: (immediate: Boolean) -> Unit + @Mock lateinit var falsingManager: FalsingManager + @Mock lateinit var logSmartspaceImpression: (Boolean) -> Unit + @Mock lateinit var logger: MediaUiEventLogger + + lateinit var executor: FakeExecutor + private val clock = FakeSystemClock() + + private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + executor = FakeExecutor(clock) + mediaCarouselScrollHandler = + MediaCarouselScrollHandler( + mediaCarousel, + pageIndicator, + executor, + dismissCallback, + translationChangedListener, + seekBarUpdateListener, + closeGuts, + falsingManager, + logSmartspaceImpression, + logger + ) + mediaCarouselScrollHandler.playerWidthPlusPadding = carouselWidth + + whenever(mediaCarousel.touchListener).thenReturn(mediaCarouselScrollHandler.touchListener) + } + + @Test + fun testCarouselScroll_shortScroll() { + whenever(mediaCarousel.isLayoutRtl).thenReturn(false) + whenever(mediaCarousel.relativeScrollX).thenReturn(300) + + mediaCarousel.touchListener?.onTouchEvent(motionEventUp) + executor.runAllReady() + + verify(mediaCarousel).smoothScrollTo(eq(0), anyInt()) + } + + @Test + fun testCarouselScroll_shortScroll_isRTL() { + whenever(mediaCarousel.isLayoutRtl).thenReturn(true) + whenever(mediaCarousel.relativeScrollX).thenReturn(300) + + mediaCarousel.touchListener?.onTouchEvent(motionEventUp) + executor.runAllReady() + + verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt()) + } + + @Test + fun testCarouselScroll_longScroll() { + whenever(mediaCarousel.isLayoutRtl).thenReturn(false) + whenever(mediaCarousel.relativeScrollX).thenReturn(600) + + mediaCarousel.touchListener?.onTouchEvent(motionEventUp) + executor.runAllReady() + + verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt()) + } + + @Test + fun testCarouselScroll_longScroll_isRTL() { + whenever(mediaCarousel.isLayoutRtl).thenReturn(true) + whenever(mediaCarousel.relativeScrollX).thenReturn(600) + + mediaCarousel.touchListener?.onTouchEvent(motionEventUp) + executor.runAllReady() + + verify(mediaCarousel).smoothScrollTo(eq(0), anyInt()) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt index 55ea31571dfe..65697b736cbd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt @@ -24,6 +24,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.statusbar.notification.collection.GroupEntry import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotifPipeline @@ -77,13 +78,18 @@ class ConversationCoordinatorTest : SysuiTestCase() { private lateinit var coordinator: ConversationCoordinator + private val featureFlags = FakeFeatureFlagsClassic() + @Before fun setUp() { MockitoAnnotations.initMocks(this) coordinator = ConversationCoordinator( peopleNotificationIdentifier, conversationIconManager, - HighPriorityProvider(peopleNotificationIdentifier, GroupMembershipManagerImpl()), + HighPriorityProvider( + peopleNotificationIdentifier, + GroupMembershipManagerImpl(featureFlags) + ), headerController ) whenever(channel.isImportantConversation).thenReturn(true) @@ -182,7 +188,7 @@ class ConversationCoordinatorTest : SysuiTestCase() { } @Test - fun testInAlertingPeopleSectionWhenThereIsAnImportantChild(){ + fun testInAlertingPeopleSectionWhenThereIsAnImportantChild() { // GIVEN val altChildA = NotificationEntryBuilder().setTag("A") .setImportance(IMPORTANCE_DEFAULT).build() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt index 4a94dc819a9e..ac2aec6e0c86 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt @@ -19,13 +19,23 @@ package com.android.systemui.statusbar.notification.collection.render import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager -import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags +import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder +import com.android.systemui.statusbar.notification.collection.ListEntry +import com.android.systemui.statusbar.notification.collection.NotifPipeline import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener +import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener +import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.mock -import org.junit.Assert +import com.android.systemui.util.mockito.withArgCaptor +import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` as whenever @SmallTest @@ -34,15 +44,45 @@ class GroupExpansionManagerTest : SysuiTestCase() { private val dumpManager: DumpManager = mock() private val groupMembershipManager: GroupMembershipManager = mock() - private val featureFlags = FakeFeatureFlags() + private val featureFlags = FakeFeatureFlagsClassic() - private val entry1 = NotificationEntryBuilder().build() - private val entry2 = NotificationEntryBuilder().build() + private val pipeline: NotifPipeline = mock() + private lateinit var beforeRenderListListener: OnBeforeRenderListListener + + private val summary1 = notificationEntry("foo", 1) + private val summary2 = notificationEntry("bar", 1) + private val entries = + listOf<ListEntry>( + GroupEntryBuilder() + .setSummary(summary1) + .setChildren( + listOf( + notificationEntry("foo", 2), + notificationEntry("foo", 3), + notificationEntry("foo", 4) + ) + ) + .build(), + GroupEntryBuilder() + .setSummary(summary2) + .setChildren( + listOf( + notificationEntry("bar", 2), + notificationEntry("bar", 3), + notificationEntry("bar", 4) + ) + ) + .build(), + notificationEntry("baz", 1) + ) + + private fun notificationEntry(pkg: String, id: Int) = + NotificationEntryBuilder().setPkg(pkg).setId(id).build().apply { row = mock() } @Before fun setUp() { - whenever(groupMembershipManager.getGroupSummary(entry1)).thenReturn(entry1) - whenever(groupMembershipManager.getGroupSummary(entry2)).thenReturn(entry2) + whenever(groupMembershipManager.getGroupSummary(summary1)).thenReturn(summary1) + whenever(groupMembershipManager.getGroupSummary(summary2)).thenReturn(summary2) gem = GroupExpansionManagerImpl(dumpManager, groupMembershipManager, featureFlags) } @@ -54,16 +94,16 @@ class GroupExpansionManagerTest : SysuiTestCase() { var listenerCalledCount = 0 gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ } - gem.setGroupExpanded(entry1, false) - Assert.assertEquals(0, listenerCalledCount) - gem.setGroupExpanded(entry1, true) - Assert.assertEquals(1, listenerCalledCount) - gem.setGroupExpanded(entry2, true) - Assert.assertEquals(2, listenerCalledCount) - gem.setGroupExpanded(entry1, true) - Assert.assertEquals(2, listenerCalledCount) - gem.setGroupExpanded(entry2, false) - Assert.assertEquals(3, listenerCalledCount) + gem.setGroupExpanded(summary1, false) + assertThat(listenerCalledCount).isEqualTo(0) + gem.setGroupExpanded(summary1, true) + assertThat(listenerCalledCount).isEqualTo(1) + gem.setGroupExpanded(summary2, true) + assertThat(listenerCalledCount).isEqualTo(2) + gem.setGroupExpanded(summary1, true) + assertThat(listenerCalledCount).isEqualTo(2) + gem.setGroupExpanded(summary2, false) + assertThat(listenerCalledCount).isEqualTo(3) } @Test @@ -73,15 +113,39 @@ class GroupExpansionManagerTest : SysuiTestCase() { var listenerCalledCount = 0 gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ } - gem.setGroupExpanded(entry1, false) - Assert.assertEquals(1, listenerCalledCount) - gem.setGroupExpanded(entry1, true) - Assert.assertEquals(2, listenerCalledCount) - gem.setGroupExpanded(entry2, true) - Assert.assertEquals(3, listenerCalledCount) - gem.setGroupExpanded(entry1, true) - Assert.assertEquals(4, listenerCalledCount) - gem.setGroupExpanded(entry2, false) - Assert.assertEquals(5, listenerCalledCount) + gem.setGroupExpanded(summary1, false) + assertThat(listenerCalledCount).isEqualTo(1) + gem.setGroupExpanded(summary1, true) + assertThat(listenerCalledCount).isEqualTo(2) + gem.setGroupExpanded(summary2, true) + assertThat(listenerCalledCount).isEqualTo(3) + gem.setGroupExpanded(summary1, true) + assertThat(listenerCalledCount).isEqualTo(4) + gem.setGroupExpanded(summary2, false) + assertThat(listenerCalledCount).isEqualTo(5) + } + + @Test + fun testSyncWithPipeline() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true) + gem.attach(pipeline) + beforeRenderListListener = withArgCaptor { + verify(pipeline).addOnBeforeRenderListListener(capture()) + } + + val listener: OnGroupExpansionChangeListener = mock() + gem.registerGroupExpansionChangeListener(listener) + + beforeRenderListListener.onBeforeRenderList(entries) + verify(listener, never()).onGroupExpansionChange(any(), any()) + + // Expand one of the groups. + gem.setGroupExpanded(summary1, true) + verify(listener).onGroupExpansionChange(summary1.row, true) + + // Empty the pipeline list and verify that the group is no longer expanded. + beforeRenderListListener.onBeforeRenderList(emptyList()) + verify(listener).onGroupExpansionChange(summary1.row, false) + verifyNoMoreInteractions(listener) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt new file mode 100644 index 000000000000..37ec0e09f841 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.collection.render + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.flags.FakeFeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.statusbar.notification.collection.GroupEntry +import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder +import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test + +@SmallTest +class GroupMembershipManagerTest : SysuiTestCase() { + private lateinit var gmm: GroupMembershipManagerImpl + + private val featureFlags = FakeFeatureFlagsClassic() + + @Before + fun setUp() { + gmm = GroupMembershipManagerImpl(featureFlags) + } + + @Test + fun testIsChildInGroup_topLevel() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false) + val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build() + assertThat(gmm.isChildInGroup(topLevelEntry)).isFalse() + } + + @Test + fun testIsChildInGroup_noParent_old() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false) + val noParentEntry = NotificationEntryBuilder().setParent(null).build() + assertThat(gmm.isChildInGroup(noParentEntry)).isTrue() + } + + @Test + fun testIsChildInGroup_noParent_new() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true) + val noParentEntry = NotificationEntryBuilder().setParent(null).build() + assertThat(gmm.isChildInGroup(noParentEntry)).isFalse() + } + + @Test + fun testIsChildInGroup_child() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false) + val childEntry = NotificationEntryBuilder().build() + assertThat(gmm.isChildInGroup(childEntry)).isTrue() + } + + @Test + fun testIsGroupSummary() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true) + val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build() + assertThat(gmm.isGroupSummary(entry)).isTrue() + } + + @Test + fun testGetGroupSummary() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true) + + val summary = + NotificationEntryBuilder() + .setGroup(mContext, "group") + .setGroupSummary(mContext, true) + .build() + val groupEntry = + GroupEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).setSummary(summary).build() + val entry = + NotificationEntryBuilder().setGroup(mContext, "group").setParent(groupEntry).build() + + assertThat(gmm.getGroupSummary(entry)).isEqualTo(summary) + } + + @Test + fun testGetGroupSummary_isSummary_old() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false) + val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build() + assertThat(gmm.getGroupSummary(entry)).isNull() + } + + @Test + fun testGetGroupSummary_isSummary_new() { + featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true) + val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build() + assertThat(gmm.getGroupSummary(entry)).isEqualTo(entry) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index ea87c808debd..e52cb572f289 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -135,7 +135,8 @@ public class NotificationContentInflaterTest extends SysuiTestCase { mock(MediaFeatureFlag.class), mock(Executor.class), mSmartReplyStateInflater, - mNotifLayoutInflaterFactoryProvider); + mNotifLayoutInflaterFactoryProvider, + mock(NotificationContentInflaterLogger.class)); } @Test @@ -258,7 +259,8 @@ public class NotificationContentInflaterTest extends SysuiTestCase { return new AsyncFailRemoteView(mContext.getPackageName(), R.layout.custom_view_dark); } - }); + }, + mock(NotificationContentInflaterLogger.class)); assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS)); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 9dfcb3f75eb1..638694038a6a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -174,7 +174,8 @@ public class NotificationTestHelper { mock(MediaFeatureFlag.class), mock(Executor.class), new MockSmartReplyInflater(), - mock(NotifLayoutInflaterFactory.Provider.class)); + mock(NotifLayoutInflaterFactory.Provider.class), + mock(NotificationContentInflaterLogger.class)); contentBinder.setInflateSynchronously(true); mBindStage = new RowContentBindStage(contentBinder, mock(NotifInflationErrorManager.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index 5a1450f1c57b..4e3690f1d124 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -162,7 +162,7 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; -import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent; +import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -195,6 +195,8 @@ import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.util.Optional; +import javax.inject.Provider; + @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper(setAsMainLooper = true) @@ -259,6 +261,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private DynamicPrivacyController mDynamicPrivacyController; @Mock private AutoHideController mAutoHideController; @Mock private StatusBarWindowController mStatusBarWindowController; + @Mock private Provider<CollapsedStatusBarFragment> mCollapsedStatusBarFragmentProvider; @Mock private StatusBarWindowStateController mStatusBarWindowStateController; @Mock private UserSwitcherController mUserSwitcherController; @Mock private Bubbles mBubbles; @@ -277,8 +280,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback; @Mock private VolumeComponent mVolumeComponent; @Mock private CommandQueue mCommandQueue; - @Mock private CentralSurfacesComponent.Factory mStatusBarComponentFactory; - @Mock private CentralSurfacesComponent mCentralSurfacesComponent; @Mock private CentralSurfacesCommandQueueCallbacks mCentralSurfacesCommandQueueCallbacks; @Mock private PluginManager mPluginManager; @Mock private ViewMediatorCallback mViewMediatorCallback; @@ -405,7 +406,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { when(mNotificationShadeWindowViewControllerLazy.get()) .thenReturn(mNotificationShadeWindowViewController); - when(mStatusBarComponentFactory.create()).thenReturn(mCentralSurfacesComponent); doAnswer(invocation -> { ((Runnable) invocation.getArgument(0)).run(); return null; @@ -443,7 +443,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mock(FragmentService.class), mLightBarController, mAutoHideController, - new StatusBarInitializer(mStatusBarWindowController, emptySet()), + new StatusBarInitializer( + mStatusBarWindowController, + mCollapsedStatusBarFragmentProvider, + emptySet()), mStatusBarWindowController, mStatusBarWindowStateController, mKeyguardUpdateMonitor, @@ -504,7 +507,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mDozeScrimController, mVolumeComponent, mCommandQueue, - mStatusBarComponentFactory, () -> mCentralSurfacesCommandQueueCallbacks, mPluginManager, mShadeController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt index e76f26d8128e..e6f8c4861a94 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt @@ -134,6 +134,22 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { verify(shadeViewController, times(1)).showAodUi() } + @Test + fun testAodUiShowNotInvokedIfWakingUp() { + `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true) + `when`(powerManager.isInteractive).thenReturn(false) + + val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java) + controller.startAnimation() + controller.onStartedWakingUp() + + verify(handler).postDelayed(callbackCaptor.capture(), anyLong()) + + callbackCaptor.value.run() + + verify(shadeViewController, never()).showAodUi() + } + /** * The AOD UI is shown during the screen off animation, after a delay to allow the light reveal * animation to start. If the device is woken up during the screen off, we should *never* do diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt index 8c1ef1deb0da..11ea513c53e7 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt @@ -23,7 +23,9 @@ import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeCommandQueue import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.shade.data.repository.FakeShadeRepository +import com.android.systemui.util.mockito.mock /** * Simply put, I got tired of adding a constructor argument and then having to tweak dozens of @@ -40,6 +42,7 @@ object KeyguardInteractorFactory { bouncerRepository: FakeKeyguardBouncerRepository = FakeKeyguardBouncerRepository(), configurationRepository: FakeConfigurationRepository = FakeConfigurationRepository(), shadeRepository: FakeShadeRepository = FakeShadeRepository(), + sceneInteractor: SceneInteractor = mock(), ): WithDependencies { return WithDependencies( repository = repository, @@ -55,6 +58,7 @@ object KeyguardInteractorFactory { bouncerRepository = bouncerRepository, configurationRepository = configurationRepository, shadeRepository = shadeRepository, + sceneInteractorProvider = { sceneInteractor }, ) ) } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorFactory.kt index 05c63b6cea72..5cf656ceedaa 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorFactory.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorFactory.kt @@ -16,6 +16,8 @@ package com.android.systemui.keyguard.domain.interactor +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.util.mockito.mock import dagger.Lazy @@ -31,8 +33,9 @@ object KeyguardTransitionInteractorFactory { fun create( scope: CoroutineScope, repository: FakeKeyguardTransitionRepository = FakeKeyguardTransitionRepository(), + featureFlags: FakeFeatureFlags = FakeFeatureFlagsClassic(), keyguardInteractor: KeyguardInteractor = - KeyguardInteractorFactory.create().keyguardInteractor, + KeyguardInteractorFactory.create(featureFlags = featureFlags).keyguardInteractor, fromLockscreenTransitionInteractor: Lazy<FromLockscreenTransitionInteractor> = Lazy { mock<FromLockscreenTransitionInteractor>() }, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt index f7db44e9618a..282d79833baa 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt @@ -167,6 +167,7 @@ class SceneTestUtils( bouncerRepository = FakeKeyguardBouncerRepository(), configurationRepository = FakeConfigurationRepository(), shadeRepository = FakeShadeRepository(), + sceneInteractorProvider = { sceneInteractor() }, ) } diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp index 8acc5089f8bd..155dc1a68295 100644 --- a/packages/WallpaperBackup/Android.bp +++ b/packages/WallpaperBackup/Android.bp @@ -27,9 +27,6 @@ android_app { name: "WallpaperBackup", defaults: ["platform_app_defaults"], srcs: ["src/**/*.java"], - optimize: { - proguard_flags_files: ["proguard.flags"], - }, platform_apis: true, certificate: "platform", privileged: false, diff --git a/packages/WallpaperBackup/proguard.flags b/packages/WallpaperBackup/proguard.flags deleted file mode 100644 index 247e6efb10ef..000000000000 --- a/packages/WallpaperBackup/proguard.flags +++ /dev/null @@ -1 +0,0 @@ --keep class com.android.wallpaperbackup.WallpaperBackupAgent diff --git a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java index 66755688fb19..ce4067cf3786 100644 --- a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java +++ b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java @@ -19,6 +19,7 @@ package com.android.server.companion.virtual; import static android.hardware.camera2.CameraInjectionSession.InjectionStatusCallback.ERROR_INJECTION_UNSUPPORTED; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -146,6 +147,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen * * @param runningUids uids of the application running on the virtual display */ + @RequiresPermission(android.Manifest.permission.CAMERA_INJECT_EXTERNAL_CAMERA) public void blockCameraAccessIfNeeded(Set<Integer> runningUids) { synchronized (mLock) { for (int i = 0; i < mAppsToBlockOnVirtualDevice.size(); i++) { @@ -181,6 +183,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen } @Override + @RequiresPermission(android.Manifest.permission.CAMERA_INJECT_EXTERNAL_CAMERA) public void onCameraOpened(@NonNull String cameraId, @NonNull String packageName) { synchronized (mLock) { InjectionSessionData data = mPackageToSessionData.get(packageName); @@ -243,6 +246,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen /** * Turns on blocking for a particular camera and package. */ + @RequiresPermission(android.Manifest.permission.CAMERA_INJECT_EXTERNAL_CAMERA) private void startBlocking(String packageName, String cameraId) { try { Slog.d( diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index 34033e225b80..9e7b897119a1 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -17,6 +17,7 @@ package com.android.server.companion.virtual; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; +import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -46,7 +47,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.BlockedAppStreamingActivity; -import java.util.List; import java.util.Set; @@ -136,7 +136,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @Nullable private final SecureWindowCallback mSecureWindowCallback; @Nullable private final Set<String> mDisplayCategories; - private final boolean mShowTasksInHostDeviceRecents; + @GuardedBy("mGenericWindowPolicyControllerLock") + private boolean mShowTasksInHostDeviceRecents; /** * Creates a window policy controller that is generic to the different use cases of virtual @@ -204,6 +205,15 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController mDisplayId = displayId; } + /** + * Set whether to show activities in recents on the host device. + */ + public void setShowInHostDeviceRecents(boolean showInHostDeviceRecents) { + synchronized (mGenericWindowPolicyControllerLock) { + mShowTasksInHostDeviceRecents = showInHostDeviceRecents; + } + } + /** Register a listener for running applications changes. */ public void registerRunningAppsChangedListener(@NonNull RunningAppsChangedListener listener) { synchronized (mGenericWindowPolicyControllerLock) { @@ -219,70 +229,75 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } @Override - public boolean canContainActivities(@NonNull List<ActivityInfo> activities, - @WindowConfiguration.WindowingMode int windowingMode) { - if (!isWindowingModeSupported(windowingMode)) { + public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, + @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode, + int launchingFromDisplayId, boolean isNewTask) { + if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId, isNewTask)) { + mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); return false; } - // Can't display all the activities if any of them don't want to be displayed. - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - final ActivityInfo aInfo = activities.get(i); - if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { - mActivityBlockedCallback.onActivityBlocked(mDisplayId, aInfo); - return false; - } + if (mIntentListenerCallback != null && intent != null + && mIntentListenerCallback.shouldInterceptIntent(intent)) { + Slog.d(TAG, "Virtual device intercepting intent"); + return false; } return true; } @Override - public boolean canActivityBeLaunched(ActivityInfo activityInfo, - Intent intent, @WindowConfiguration.WindowingMode int windowingMode, - int launchingFromDisplayId, boolean isNewTask) { + public boolean canContainActivity(@NonNull ActivityInfo activityInfo, + @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, + boolean isNewTask) { if (!isWindowingModeSupported(windowingMode)) { + Slog.d(TAG, "Virtual device doesn't support windowing mode " + windowingMode); return false; } - - final ComponentName activityComponent = activityInfo.getComponentName(); - if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { - // The error dialog alerting users that streaming is blocked is always allowed. - return true; + if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { + Slog.d(TAG, "Virtual device requires android:canDisplayOnRemoteDevices=true"); + return false; } - - if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { - mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); + final UserHandle activityUser = + UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); + if (!mAllowedUsers.contains(activityUser)) { + Slog.d(TAG, "Virtual device launch disallowed from user " + activityUser); return false; } - if (launchingFromDisplayId == Display.DEFAULT_DISPLAY) { + final ComponentName activityComponent = activityInfo.getComponentName(); + if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { + // The error dialog alerting users that streaming is blocked is always allowed. return true; } - if (isNewTask && !mBlockedCrossTaskNavigations.isEmpty() - && mBlockedCrossTaskNavigations.contains(activityComponent)) { - Slog.d(TAG, "Virtual device blocking cross task navigation of " + activityComponent); - mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); + if (!activityMatchesDisplayCategory(activityInfo)) { + Slog.d(TAG, "The activity's required display category '" + + activityInfo.requiredDisplayCategory + + "' not found on virtual display with the following categories: " + + mDisplayCategories); return false; } - if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty() - && !mAllowedCrossTaskNavigations.contains(activityComponent)) { - Slog.d(TAG, "Virtual device not allowing cross task navigation of " - + activityComponent); - mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); + if ((mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED + && mBlockedActivities.contains(activityComponent)) + || (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED + && !mAllowedActivities.contains(activityComponent))) { + Slog.d(TAG, "Virtual device launch disallowed by policy: " + activityComponent); return false; } - - if (mIntentListenerCallback != null && intent != null - && mIntentListenerCallback.shouldInterceptIntent(intent)) { - Slog.d(TAG, "Virtual device has intercepted intent"); - return false; + if (isNewTask && launchingFromDisplayId != DEFAULT_DISPLAY) { + if ((!mBlockedCrossTaskNavigations.isEmpty() + && mBlockedCrossTaskNavigations.contains(activityComponent)) + || ((!mAllowedCrossTaskNavigations.isEmpty() + && !mAllowedCrossTaskNavigations.contains(activityComponent)))) { + Slog.d(TAG, "Virtual device cross task navigation disallowed by policy: " + + activityComponent); + return false; + } } return true; } - @Override + @SuppressWarnings("AndroidFrameworkRequiresPermission") public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { // The callback is fired only when windowFlags are changed. To let VirtualDevice owner @@ -293,10 +308,17 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController activityInfo.applicationInfo.uid)); } - if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) { - mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); - return false; + if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, + activityInfo.packageName, + UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid))) { + // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. + if ((windowFlags & FLAG_SECURE) != 0 + || (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { + mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo); + return false; + } } + return true; } @@ -335,7 +357,9 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @Override public boolean canShowTasksInHostDeviceRecents() { - return mShowTasksInHostDeviceRecents; + synchronized (mGenericWindowPolicyControllerLock) { + return mShowTasksInHostDeviceRecents; + } } @Override @@ -368,53 +392,6 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController } - private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags, - int systemWindowFlags) { - if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) { - return false; - } - ComponentName activityComponent = activityInfo.getComponentName(); - if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) { - // The error dialog alerting users that streaming is blocked is always allowed. Need to - // run before the clauses below to ensure error dialog always shows up. - return true; - } - if (!activityMatchesDisplayCategory(activityInfo)) { - Slog.d(TAG, String.format( - "The activity's required display category: %s is not found on virtual display" - + " with the following categories: %s", - activityInfo.requiredDisplayCategory, mDisplayCategories.toString())); - return false; - } - final UserHandle activityUser = - UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid); - if (!mAllowedUsers.contains(activityUser)) { - Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser); - return false; - } - if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED - && mBlockedActivities.contains(activityComponent)) { - Slog.d(TAG, "Virtual device blocking launch of " + activityComponent); - return false; - } - if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED - && !mAllowedActivities.contains(activityComponent)) { - Slog.d(TAG, activityComponent + " is not in the allowed list."); - return false; - } - if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE, - activityInfo.packageName, activityUser)) { - // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure. - if ((windowFlags & FLAG_SECURE) != 0) { - return false; - } - if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) { - return false; - } - } - return true; - } - @VisibleForTesting int getRunningAppsChangedListenersSizeForTesting() { synchronized (mGenericWindowPolicyControllerLock) { diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java index 307f7bfc1fd5..eeaa423b1aef 100644 --- a/services/companion/java/com/android/server/companion/virtual/InputController.java +++ b/services/companion/java/com/android/server/companion/virtual/InputController.java @@ -16,6 +16,8 @@ package com.android.server.companion.virtual; +import static android.text.TextUtils.formatSimple; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.StringDef; @@ -350,7 +352,7 @@ class InputController { } private static String createPhys(@PhysType String type) { - return String.format("virtual%s:%d", type, sNextPhysId.getAndIncrement()); + return formatSimple("virtual%s:%d", type, sNextPhysId.getAndIncrement()); } private void setUniqueIdAssociation(int displayId, String phys) { diff --git a/services/companion/java/com/android/server/companion/virtual/SensorController.java b/services/companion/java/com/android/server/companion/virtual/SensorController.java index a831401168af..e9241dddcde9 100644 --- a/services/companion/java/com/android/server/companion/virtual/SensorController.java +++ b/services/companion/java/com/android/server/companion/virtual/SensorController.java @@ -323,8 +323,5 @@ public class SensorController { SensorCreationException(String message) { super(message); } - SensorCreationException(String message, Exception cause) { - super(message, cause); - } } } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index f23fe2a7bce4..56afeb112068 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -19,12 +19,15 @@ package com.android.server.companion.virtual; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_ENABLED; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; import static android.app.admin.DevicePolicyManager.NEARBY_STREAMING_SAME_MANAGED_ACCOUNT_ONLY; +import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; +import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.StringRes; import android.annotation.UserIdInt; import android.app.Activity; @@ -41,6 +44,7 @@ import android.companion.virtual.VirtualDeviceManager.ActivityListener; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; +import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorEvent; import android.content.AttributionSource; @@ -78,12 +82,15 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseIntArray; import android.view.Display; import android.view.WindowManager; import android.widget.Toast; + import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.BlockedAppStreamingActivity; @@ -93,7 +100,6 @@ import com.android.server.companion.virtual.audio.VirtualAudioController; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -128,8 +134,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final int mOwnerUid; private final VirtualDeviceLog mVirtualDeviceLog; private final String mOwnerPackageName; - private int mDeviceId; - private @Nullable String mPersistentDeviceId; + private final int mDeviceId; + private @Nullable final String mPersistentDeviceId; // Thou shall not hold the mVirtualDeviceLock over the mInputController calls. // Holding the lock can lead to lock inversion with GlobalWindowManagerLock. // 1. After display is created the window manager calls into VDM during construction @@ -145,6 +151,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final IBinder mAppToken; private final VirtualDeviceParams mParams; @GuardedBy("mVirtualDeviceLock") + private final SparseIntArray mDevicePolicies; + @GuardedBy("mVirtualDeviceLock") private final SparseArray<VirtualDisplayWrapper> mVirtualDisplays = new SparseArray<>(); private final IVirtualDeviceActivityListener mActivityListener; private final IVirtualDeviceSoundEffectListener mSoundEffectListener; @@ -152,7 +160,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @GuardedBy("mVirtualDeviceLock") private final Map<IBinder, IntentFilter> mIntentInterceptors = new ArrayMap<>(); @NonNull - private Consumer<ArraySet<Integer>> mRunningAppsChangedCallback; + private final Consumer<ArraySet<Integer>> mRunningAppsChangedCallback; // The default setting for showing the pointer on new displays. @GuardedBy("mVirtualDeviceLock") private boolean mDefaultShowPointerIcon = true; @@ -259,6 +267,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mDeviceId = deviceId; mAppToken = token; mParams = params; + mDevicePolicies = params.getDevicePolicies(); mDisplayManager = displayManager; if (inputController == null) { mInputController = new InputController( @@ -321,7 +330,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub /** Returns the policy specified for this policy type */ public @VirtualDeviceParams.DevicePolicy int getDevicePolicy( @VirtualDeviceParams.PolicyType int policyType) { - return mParams.getDevicePolicy(policyType); + if (Flags.dynamicPolicy()) { + synchronized (mVirtualDeviceLock) { + return mDevicePolicies.get(policyType, DEVICE_POLICY_DEFAULT); + } + } else { + return mParams.getDevicePolicy(policyType); + } } /** Returns device-specific audio session id for playback. */ @@ -410,15 +425,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub public void close() { super.close_enforcePermission(); // Remove about-to-be-closed virtual device from the service before butchering it. - boolean removed = mService.removeVirtualDevice(mDeviceId); - mVirtualDeviceLog.logClosed(mDeviceId, mOwnerUid); - mDeviceId = Context.DEVICE_ID_INVALID; - - // Device is already closed. - if (!removed) { + if (!mService.removeVirtualDevice(mDeviceId)) { + // Device is already closed. return; } + mVirtualDeviceLog.logClosed(mDeviceId, mOwnerUid); + final long ident = Binder.clearCallingIdentity(); try { VirtualDisplayWrapper[] virtualDisplaysToBeReleased; @@ -460,6 +473,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } @Override + @RequiresPermission(android.Manifest.permission.CAMERA_INJECT_EXTERNAL_CAMERA) public void onRunningAppsChanged(ArraySet<Integer> runningUids) { mCameraAccessController.blockCameraAccessIfNeeded(runningUids); mRunningAppsChangedCallback.accept(runningUids); @@ -507,6 +521,27 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @Override // Binder call @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) + public void setDevicePolicy(@VirtualDeviceParams.DynamicPolicyType int policyType, + @VirtualDeviceParams.DevicePolicy int devicePolicy) { + super.setDevicePolicy_enforcePermission(); + switch (policyType) { + case POLICY_TYPE_RECENTS: + synchronized (mVirtualDeviceLock) { + mDevicePolicies.put(policyType, devicePolicy); + for (int i = 0; i < mVirtualDisplays.size(); i++) { + mVirtualDisplays.valueAt(i).getWindowPolicyController() + .setShowInHostDeviceRecents(devicePolicy == DEVICE_POLICY_DEFAULT); + } + } + break; + default: + throw new IllegalArgumentException("Device policy " + policyType + + " cannot be changed at runtime. "); + } + } + + @Override // Binder call + @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void createVirtualDpad(VirtualDpadConfig config, @NonNull IBinder deviceToken) { super.createVirtualDpad_enforcePermission(); Objects.requireNonNull(config); @@ -718,11 +753,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub try { synchronized (mVirtualDeviceLock) { mDefaultShowPointerIcon = showPointerIcon; - for (int i = 0; i < mVirtualDisplays.size(); i++) { - final int displayId = mVirtualDisplays.keyAt(i); - mInputController.setShowPointerIcon(mDefaultShowPointerIcon, displayId); - } } + getDisplayIds().forEach( + displayId -> mInputController.setShowPointerIcon(showPointerIcon, displayId)); } finally { Binder.restoreCallingIdentity(ident); } @@ -786,6 +819,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mParams.dump(fout, " "); fout.println(" mVirtualDisplayIds: "); synchronized (mVirtualDeviceLock) { + fout.println(" mDevicePolicies: " + mDevicePolicies); for (int i = 0; i < mVirtualDisplays.size(); i++) { fout.println(" " + mVirtualDisplays.keyAt(i)); } @@ -812,9 +846,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub this::onSecureWindowShown, this::shouldInterceptIntent, displayCategories, - mParams.getDevicePolicy( - VirtualDeviceParams.POLICY_TYPE_RECENTS) - == VirtualDeviceParams.DEVICE_POLICY_DEFAULT); + mParams.getDevicePolicy(POLICY_TYPE_RECENTS) == DEVICE_POLICY_DEFAULT); gwpc.registerRunningAppsChangedListener(/* listener= */ this); return gwpc; } @@ -830,6 +862,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub this, gwpc, packageName); gwpc.setDisplayId(displayId); + boolean showPointer; synchronized (mVirtualDeviceLock) { if (mVirtualDisplays.contains(displayId)) { gwpc.unregisterRunningAppsChangedListener(this); @@ -839,11 +872,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub PowerManager.WakeLock wakeLock = createAndAcquireWakeLockForDisplay(displayId); mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock)); + showPointer = mDefaultShowPointerIcon; } final long token = Binder.clearCallingIdentity(); try { - mInputController.setShowPointerIcon(mDefaultShowPointerIcon, displayId); + mInputController.setShowPointerIcon(showPointer, displayId); mInputController.setPointerAcceleration(1f, displayId); mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false, displayId); @@ -869,6 +903,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) private void onActivityBlocked(int displayId, ActivityInfo activityInfo) { Intent intent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -950,6 +985,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + @SuppressWarnings("AndroidFrameworkRequiresPermission") private void checkVirtualInputDeviceDisplayIdAssociation(int displayId) { if (mContext.checkCallingPermission(android.Manifest.permission.INJECT_EVENTS) == PackageManager.PERMISSION_GRANTED) { @@ -1031,8 +1067,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub */ void showToastWhereUidIsRunning(int uid, String text, @Toast.Duration int duration, Looper looper) { - ArrayList<Integer> displayIdsForUid = getDisplayIdsWhereUidIsRunning(uid); - if (displayIdsForUid.isEmpty()) { + IntArray displayIdsForUid = getDisplayIdsWhereUidIsRunning(uid); + if (displayIdsForUid.size() == 0) { return; } DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); @@ -1045,8 +1081,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } - private ArrayList<Integer> getDisplayIdsWhereUidIsRunning(int uid) { - ArrayList<Integer> displayIdsForUid = new ArrayList<>(); + private IntArray getDisplayIdsWhereUidIsRunning(int uid) { + IntArray displayIdsForUid = new IntArray(); synchronized (mVirtualDeviceLock) { for (int i = 0; i < mVirtualDisplays.size(); i++) { if (mVirtualDisplays.valueAt(i).getWindowPolicyController().containsUid(uid)) { diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java index 7429fbe18a0c..4da929816d2f 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java @@ -23,6 +23,7 @@ import static com.android.server.wm.ActivityInterceptorCallback.VIRTUAL_DEVICE_S import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.app.ActivityOptions; import android.companion.AssociationInfo; @@ -34,6 +35,7 @@ import android.companion.virtual.IVirtualDeviceSoundEffectListener; import android.companion.virtual.VirtualDevice; import android.companion.virtual.VirtualDeviceManager; import android.companion.virtual.VirtualDeviceParams; +import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.VirtualSensor; import android.content.AttributionSource; import android.content.Context; @@ -95,6 +97,7 @@ public class VirtualDeviceManagerService extends SystemService { private final CompanionDeviceManager.OnAssociationsChangedListener mCdmAssociationListener = new CompanionDeviceManager.OnAssociationsChangedListener() { @Override + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void onAssociationsChanged(@NonNull List<AssociationInfo> associations) { syncVirtualDevicesToCdmAssociations(associations); } @@ -240,6 +243,7 @@ public class VirtualDeviceManagerService extends SystemService { return true; } + @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) private void syncVirtualDevicesToCdmAssociations(List<AssociationInfo> associations) { Set<VirtualDeviceImpl> virtualDevicesToRemove = new HashSet<>(); synchronized (mVirtualDeviceManagerLock) { @@ -265,6 +269,7 @@ public class VirtualDeviceManagerService extends SystemService { } } + @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) private void registerCdmAssociationListener() { final CompanionDeviceManager cdm = getContext().getSystemService( CompanionDeviceManager.class); @@ -272,6 +277,7 @@ public class VirtualDeviceManagerService extends SystemService { mCdmAssociationListener); } + @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) private void unregisterCdmAssociationListener() { final CompanionDeviceManager cdm = getContext().getSystemService( CompanionDeviceManager.class); @@ -323,6 +329,15 @@ public class VirtualDeviceManagerService extends SystemService { @NonNull IVirtualDeviceSoundEffectListener soundEffectListener) { createVirtualDevice_enforcePermission(); attributionSource.enforceCallingUid(); + final long identity = Binder.clearCallingIdentity(); + try { + if (Flags.moreLogs()) { + Slog.i(TAG, "Creating VirtualDevice"); + } + } finally { + Binder.restoreCallingIdentity(identity); + } + final int callingUid = getCallingUid(); final String packageName = attributionSource.getPackageName(); if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) { diff --git a/services/companion/java/com/android/server/companion/virtual/flags.aconfig b/services/companion/java/com/android/server/companion/virtual/flags.aconfig index 4fe4c870a283..6297e91e8705 100644 --- a/services/companion/java/com/android/server/companion/virtual/flags.aconfig +++ b/services/companion/java/com/android/server/companion/virtual/flags.aconfig @@ -1,3 +1,5 @@ +# OLD PACKAGE, DO NOT USE: Prefer `flags.aconfig` in core/java/android/companion/virtual +# (or other custom files) to define your flags package: "com.android.server.companion.virtual" flag { diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java index 557e4ac843d2..838aae8a83c0 100644 --- a/services/core/java/android/content/pm/PackageManagerInternal.java +++ b/services/core/java/android/content/pm/PackageManagerInternal.java @@ -1409,4 +1409,10 @@ public abstract class PackageManagerInternal { */ public abstract boolean isPackageQuarantined(@NonNull String packageName, @UserIdInt int userId); + + /** + * Return a list of all historical install sessions for the given user. + */ + public abstract ParceledListSlice<PackageInstaller.SessionInfo> getHistoricalSessions( + int userId); } diff --git a/services/core/java/com/android/server/LogMteState.java b/services/core/java/com/android/server/LogMteState.java index 410dd8339b30..ec0492b19f89 100644 --- a/services/core/java/com/android/server/LogMteState.java +++ b/services/core/java/com/android/server/LogMteState.java @@ -16,11 +16,12 @@ package com.android.server; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.app.StatsManager; import android.content.Context; import android.util.StatsEvent; -import com.android.internal.os.BackgroundThread; import com.android.internal.os.Zygote; import com.android.internal.util.FrameworkStatsLog; @@ -32,7 +33,7 @@ public class LogMteState { .setPullAtomCallback( FrameworkStatsLog.MTE_STATE, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, new StatsManager.StatsPullAtomCallback() { @Override public int onPullAtom(int atomTag, List<StatsEvent> data) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index bf9cdbec7b0c..0d265a0f4c4a 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3852,15 +3852,16 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void forceStopPackage(final String packageName, int userId) { - forceStopPackage(packageName, userId, /*flags=*/ 0); + forceStopPackage(packageName, userId, /*flags=*/ 0, null); } @Override public void forceStopPackageEvenWhenStopping(final String packageName, int userId) { - forceStopPackage(packageName, userId, ActivityManager.FLAG_OR_STOPPED); + forceStopPackage(packageName, userId, ActivityManager.FLAG_OR_STOPPED, null); } - private void forceStopPackage(final String packageName, int userId, int userRunningFlags) { + private void forceStopPackage(final String packageName, int userId, int userRunningFlags, + String reason) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: forceStopPackage() from pid=" @@ -3905,7 +3906,8 @@ public class ActivityManagerService extends IActivityManager.Stub + packageName + ": " + e); } if (mUserController.isUserRunning(user, userRunningFlags)) { - forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); + forceStopPackageLocked(packageName, pkgUid, + reason == null ? ("from pid " + callingPid) : reason); finishForceStopPackageLocked(packageName, pkgUid); } } @@ -5444,6 +5446,19 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { + if (allowlistToken != null) { + final int callingUid = Binder.getCallingUid(); + final String packageName; + final long token = Binder.clearCallingIdentity(); + try { + packageName = AppGlobals.getPackageManager().getNameForUid(callingUid); + } finally { + Binder.restoreCallingIdentity(token); + } + Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target." + + " Calling package: " + packageName + "; intent: " + intent + + "; options: " + options); + } target.send(code, intent, resolvedType, allowlistToken, null, requiredPermission, options); } catch (RemoteException e) { @@ -14898,8 +14913,8 @@ public class ActivityManagerService extends IActivityManager.Stub Intent.EXTRA_QUARANTINED, false); if (suspended && quarantined && packageNames != null) { for (int i = 0; i < packageNames.length; i++) { - forceStopPackageLocked(packageNames[i], -1, false, true, true, - false, false, userId, "suspended"); + forceStopPackage(packageNames[i], userId, + ActivityManager.FLAG_OR_STOPPED, "quarantined"); } } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 610b8af48cd1..2249607863d5 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -27,9 +27,12 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.RequiresNoPermission; +import android.annotation.SuppressLint; import android.app.StatsManager; import android.app.usage.NetworkStatsManager; import android.bluetooth.BluetoothActivityEnergyInfo; @@ -81,6 +84,7 @@ import android.os.health.HealthStatsParceler; import android.os.health.HealthStatsWriter; import android.os.health.UidHealthStats; import android.power.PowerStatsInternal; +import android.provider.DeviceConfig; import android.provider.Settings; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ModemActivityInfo; @@ -94,7 +98,6 @@ import android.util.StatsEvent; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; -import com.android.internal.os.BackgroundThread; import com.android.internal.os.BinderCallsStats; import com.android.internal.os.CpuScalingPolicies; import com.android.internal.os.CpuScalingPolicyReader; @@ -174,6 +177,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub .replaceWith("?"); private static final int MAX_LOW_POWER_STATS_SIZE = 32768; private static final int POWER_STATS_QUERY_TIMEOUT_MILLIS = 2000; + private static final String MIN_CONSUMED_POWER_THRESHOLD_KEY = "min_consumed_power_threshold"; private static final String EMPTY = "Empty"; private final HandlerThread mHandlerThread; @@ -844,15 +848,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); statsManager.setPullAtomCallback( FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), pullAtomCallback); + DIRECT_EXECUTOR, pullAtomCallback); } /** StatsPullAtomCallback for pulling BatteryUsageStats data. */ @@ -862,12 +866,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub final BatteryUsageStats bus; switch (atomTag) { case FrameworkStatsLog.BATTERY_USAGE_STATS_SINCE_RESET: + @SuppressLint("MissingPermission") + final double minConsumedPowerThreshold = + DeviceConfig.getFloat(DeviceConfig.NAMESPACE_BATTERY_STATS, + MIN_CONSUMED_POWER_THRESHOLD_KEY, 0); final BatteryUsageStatsQuery querySinceReset = new BatteryUsageStatsQuery.Builder() .setMaxStatsAgeMs(0) .includeProcessStateData() .includeVirtualUids() .includePowerModels() + .setMinConsumedPowerThreshold(minConsumedPowerThreshold) .build(); bus = getBatteryUsageStats(List.of(querySinceReset)).get(0); break; diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index 9219623a031d..095d907d7df6 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -1975,9 +1975,10 @@ public class ContentProviderHelper { return mProviderMap.dumpProviderProto(fd, pw, name, args); } - private Boolean isAuthorityRedirectedForCloneProfileCached(String auth) { + private boolean isAuthorityRedirectedForCloneProfileCached(String auth) { if (mCloneProfileAuthorityRedirectionCache.containsKey(auth)) { - return mCloneProfileAuthorityRedirectionCache.get(auth); + final Boolean retVal = mCloneProfileAuthorityRedirectionCache.get(auth); + return retVal == null ? false : retVal.booleanValue(); } else { boolean isAuthRedirected = isAuthorityRedirectedForCloneProfile(auth); mCloneProfileAuthorityRedirectionCache.put(auth, isAuthRedirected); diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 36b8283dd3a1..bbda952970ae 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -117,20 +117,21 @@ public class SettingsToPropertiesMapper { // All the aconfig flags under the listed DeviceConfig scopes will be synced to native level. @VisibleForTesting static final String[] sDeviceConfigAconfigScopes = new String[] { - "core_experiments_team_internal", - "camera_platform", - "power", - "vibrator", - "haptics", - "text", - "arc_next", - "test_suites", - "hardware_backed_security_mainline", - "threadnetwork", - "media_solutions", - "responsible_apis", - "rust", - "pixel_biometrics", + "biometrics_framework", + "core_experiments_team_internal", + "camera_platform", + "power", + "vibrator", + "haptics", + "text", + "arc_next", + "test_suites", + "hardware_backed_security_mainline", + "threadnetwork", + "media_solutions", + "responsible_apis", + "rust", + "pixel_biometrics", }; private final String[] mGlobalSettings; diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 81397b4d1e9f..905589f70dc1 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -25,6 +25,7 @@ import static com.android.internal.R.styleable.GameModeConfig_allowGameDownscali import static com.android.internal.R.styleable.GameModeConfig_allowGameFpsOverride; import static com.android.internal.R.styleable.GameModeConfig_supportsBatteryGameMode; import static com.android.internal.R.styleable.GameModeConfig_supportsPerformanceGameMode; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import android.Manifest; import android.annotation.NonNull; @@ -2087,17 +2088,17 @@ public final class GameManagerService extends IGameManagerService.Stub { statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_CONFIGURATION, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.GAME_MODE_LISTENER, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/appop/AttributedOp.java b/services/core/java/com/android/server/appop/AttributedOp.java index dcc36bcf6149..0ded75a848ac 100644 --- a/services/core/java/com/android/server/appop/AttributedOp.java +++ b/services/core/java/com/android/server/appop/AttributedOp.java @@ -199,28 +199,18 @@ final class AttributedOp { @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) throws RemoteException { - started(clientId, proxyUid, proxyPackageName, proxyAttributionTag, - uidState, flags, /*triggerCallbackIfNeeded*/ true, attributionFlags, - attributionChainId); - } - - private void started(@NonNull IBinder clientId, int proxyUid, - @Nullable String proxyPackageName, @Nullable String proxyAttributionTag, - @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, - boolean triggerCallbackIfNeeded, @AppOpsManager.AttributionFlags int attributionFlags, - int attributionChainId) throws RemoteException { startedOrPaused(clientId, proxyUid, proxyPackageName, - proxyAttributionTag, uidState, flags, triggerCallbackIfNeeded, - /*triggerCallbackIfNeeded*/ true, attributionFlags, attributionChainId); + proxyAttributionTag, uidState, flags, /* triggeredByUidStateChange */ false, + /* isStarted */ true, attributionFlags, attributionChainId); } @SuppressWarnings("GuardedBy") // Lock is held on mAppOpsService private void startedOrPaused(@NonNull IBinder clientId, int proxyUid, @Nullable String proxyPackageName, @Nullable String proxyAttributionTag, @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, - boolean triggerCallbackIfNeeded, boolean isStarted, @AppOpsManager.AttributionFlags + boolean triggeredByUidStateChange, boolean isStarted, @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) throws RemoteException { - if (triggerCallbackIfNeeded && !parent.isRunning() && isStarted) { + if (!triggeredByUidStateChange && !parent.isRunning() && isStarted) { mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName, tag, true, attributionFlags, attributionChainId); } @@ -263,19 +253,27 @@ final class AttributedOp { * @param clientId Id of the finishOp caller */ public void finished(@NonNull IBinder clientId) { - finished(clientId, true); + finished(clientId, false); } - private void finished(@NonNull IBinder clientId, boolean triggerCallbackIfNeeded) { - finishOrPause(clientId, triggerCallbackIfNeeded, false); + private void finished(@NonNull IBinder clientId, boolean triggeredByUidStateChange) { + finishOrPause(clientId, triggeredByUidStateChange, false); } /** * Update state when paused or finished is called. If pausing, it records the op as * stopping in the HistoricalRegistry, but does not delete it. + * + * @param triggeredByUidStateChange If {@code true}, then this method operates as usual, except + * that {@link AppOpsService#mActiveWatchers} will not be notified. This is currently only + * used in {@link #onUidStateChanged(int)}, for the purpose of restarting (i.e., + * finishing then immediately starting again in the new uid state) the AttributedOp. In this + * case, the caller is responsible for guaranteeing that either the AttributedOp is started + * again or all {@link AppOpsService#mActiveWatchers} are notified that the AttributedOp is + * finished. */ @SuppressWarnings("GuardedBy") // Lock is held on mAppOpsService - private void finishOrPause(@NonNull IBinder clientId, boolean triggerCallbackIfNeeded, + private void finishOrPause(@NonNull IBinder clientId, boolean triggeredByUidStateChange, boolean isPausing) { int indexOfToken = isRunning() ? mInProgressEvents.indexOfKey(clientId) : -1; if (indexOfToken < 0) { @@ -320,7 +318,7 @@ final class AttributedOp { mInProgressEvents = null; // TODO ntmyren: Also callback for single attribution tag activity changes - if (triggerCallbackIfNeeded && !parent.isRunning()) { + if (!triggeredByUidStateChange && !parent.isRunning()) { mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName, tag, false, event.getAttributionFlags(), event.getAttributionChainId()); @@ -368,7 +366,7 @@ final class AttributedOp { @AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) throws RemoteException { startedOrPaused(clientId, proxyUid, proxyPackageName, proxyAttributionTag, - uidState, flags, true, false, attributionFlags, attributionChainId); + uidState, flags, false, false, attributionFlags, attributionChainId); } /** @@ -386,7 +384,7 @@ final class AttributedOp { for (int i = 0; i < mInProgressEvents.size(); i++) { InProgressStartOpEvent event = mInProgressEvents.valueAt(i); mPausedInProgressEvents.put(event.getClientId(), event); - finishOrPause(event.getClientId(), true, true); + finishOrPause(event.getClientId(), false, true); mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName, tag, false, @@ -475,6 +473,8 @@ final class AttributedOp { InProgressStartOpEvent event = events.get(binders.get(i)); if (event != null && event.getUidState() != newState) { + int eventAttributionFlags = event.getAttributionFlags(); + int eventAttributionChainId = event.getAttributionChainId(); try { // Remove all but one unfinished start count and then call finished() to // remove start event object @@ -482,18 +482,18 @@ final class AttributedOp { event.mNumUnfinishedStarts = 1; AppOpsManager.OpEventProxyInfo proxy = event.getProxy(); - finished(event.getClientId(), false); + finished(event.getClientId(), true); // Call started() to add a new start event object and then add the // previously removed unfinished start counts back if (proxy != null) { startedOrPaused(event.getClientId(), proxy.getUid(), proxy.getPackageName(), proxy.getAttributionTag(), newState, - event.getFlags(), false, isRunning, + event.getFlags(), true, isRunning, event.getAttributionFlags(), event.getAttributionChainId()); } else { startedOrPaused(event.getClientId(), Process.INVALID_UID, null, null, - newState, event.getFlags(), false, isRunning, + newState, event.getFlags(), true, isRunning, event.getAttributionFlags(), event.getAttributionChainId()); } @@ -507,6 +507,9 @@ final class AttributedOp { Slog.e(AppOpsService.TAG, "Cannot switch to new uidState " + newState); } + mAppOpsService.scheduleOpActiveChangedIfNeededLocked(parent.op, + parent.uid, parent.packageName, tag, false, + eventAttributionFlags, eventAttributionChainId); } } } diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java index bd9d057f9704..6f3526fb07e9 100644 --- a/services/core/java/com/android/server/appop/HistoricalRegistry.java +++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java @@ -37,7 +37,6 @@ import android.app.AppOpsManager.UidState; import android.content.ContentResolver; import android.database.ContentObserver; import android.net.Uri; -import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Debug; @@ -46,7 +45,6 @@ import android.os.Message; import android.os.Process; import android.os.RemoteCallback; import android.os.UserHandle; -import android.provider.DeviceConfig; import android.provider.Settings; import android.util.ArraySet; import android.util.LongSparseArray; @@ -136,7 +134,6 @@ final class HistoricalRegistry { private static final String PARAMETER_DELIMITER = ","; private static final String PARAMETER_ASSIGNMENT = "="; - private static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled"; private volatile @NonNull DiscreteRegistry mDiscreteRegistry; @@ -304,10 +301,6 @@ final class HistoricalRegistry { void dump(String prefix, PrintWriter pw, int filterUid, @Nullable String filterPackage, @Nullable String filterAttributionTag, int filterOp, @HistoricalOpsRequestFilter int filter) { - if (!isApiEnabled()) { - return; - } - synchronized (mOnDiskLock) { synchronized (mInMemoryLock) { pw.println(); @@ -371,11 +364,6 @@ final class HistoricalRegistry { @OpHistoryFlags int historyFlags, @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis, @OpFlags int flags, String[] attributionExemptedPackages, @NonNull RemoteCallback callback) { - if (!isApiEnabled()) { - callback.sendResult(new Bundle()); - return; - } - final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis); if ((historyFlags & HISTORY_FLAG_AGGREGATE) != 0) { @@ -409,11 +397,6 @@ final class HistoricalRegistry { @HistoricalOpsRequestFilter int filter, long beginTimeMillis, long endTimeMillis, @OpFlags int flags, @Nullable String[] attributionExemptPkgs, @NonNull RemoteCallback callback) { - if (!isApiEnabled()) { - callback.sendResult(new Bundle()); - return; - } - final long currentTimeMillis = System.currentTimeMillis(); if (endTimeMillis == Long.MAX_VALUE) { endTimeMillis = currentTimeMillis; @@ -807,12 +790,6 @@ final class HistoricalRegistry { } } - private static boolean isApiEnabled() { - return Binder.getCallingUid() == Process.myUid() - || DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_PERMISSIONS_HUB_ENABLED, true); - } - private static final class Persistence { private static final boolean DEBUG = false; diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index a3245f0e717f..0aa9cc11c432 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -140,6 +140,7 @@ import android.media.VolumeInfo; import android.media.VolumePolicy; import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; +import android.media.audiopolicy.AudioMixingRule; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicyConfig; import android.media.audiopolicy.AudioProductStrategy; @@ -166,6 +167,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceDebugInfo; import android.os.ServiceManager; import android.os.ShellCallback; import android.os.SystemClock; @@ -10860,6 +10862,7 @@ public class AudioService extends IAudioService.Stub mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState); mDeviceBroker.persistAudioDeviceSettings(); + mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes()); mSoundDoseHelper.setAudioDeviceCategory(addr, internalType, btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES); } @@ -12048,6 +12051,49 @@ public class AudioService extends IAudioService.Stub } } + /** + * Update {@link AudioMixingRule}-s for already registered {@link AudioMix}-es. + * + * @param mixesToUpdate - array of already registered {@link AudioMix}-es to update. + * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to + * {@code mixesToUpdate} mixes. The array must be same size as + * {@code mixesToUpdate} and i-th {@link AudioMixingRule} must + * correspond to i-th {@link AudioMix} from mixesToUpdate array. + * @param pcb - {@link IAudioPolicyCallback} corresponding to the registered + * {@link AudioPolicy} all {@link AudioMix}-es for {@code mixesToUpdate} + * are part of. + * @return {@link AudioManager#SUCCESS} iff the mixing rules were updated successfully, + * {@link AudioManager#ERROR} otherwise. + */ + @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public int updateMixingRulesForPolicy( + @NonNull AudioMix[] mixesToUpdate, + @NonNull AudioMixingRule[] updatedMixingRules, + @NonNull IAudioPolicyCallback pcb) { + super.updateMixingRulesForPolicy_enforcePermission(); + Objects.requireNonNull(mixesToUpdate); + Objects.requireNonNull(updatedMixingRules); + Objects.requireNonNull(pcb); + if (mixesToUpdate.length != updatedMixingRules.length) { + Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " + + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length + + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); + return AudioManager.ERROR; + } + if (DEBUG_AP) { + Log.d(TAG, "updateMixingRules for " + pcb.asBinder() + "with mix rules: "); + } + synchronized (mAudioPolicies) { + final AudioPolicyProxy app = + checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy"); + if (app == null) { + return AudioManager.ERROR; + } + return app.updateMixingRules(mixesToUpdate, updatedMixingRules) == AudioSystem.SUCCESS + ? AudioManager.SUCCESS : AudioManager.ERROR; + } + } + /** see AudioPolicy.setUidDeviceAffinity() */ public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) { @@ -12785,6 +12831,35 @@ public class AudioService extends IAudioService.Stub } + @AudioSystem.AudioSystemError int updateMixingRules( + @NonNull AudioMix[] mixesToUpdate, + @NonNull AudioMixingRule[] updatedMixingRules) { + Objects.requireNonNull(mixesToUpdate); + Objects.requireNonNull(updatedMixingRules); + + if (mixesToUpdate.length != updatedMixingRules.length) { + Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules " + + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length + + ", updatedMixingRules.length = " + updatedMixingRules.length + ")."); + return AudioSystem.BAD_VALUE; + } + + synchronized (mMixes) { + try (SafeCloseable unused = ClearCallingIdentityContext.create()) { + int ret = mAudioSystem.updateMixingRules(mixesToUpdate, updatedMixingRules); + if (ret == AudioSystem.SUCCESS) { + for (int i = 0; i < mixesToUpdate.length; i++) { + AudioMix audioMixToUpdate = mixesToUpdate[i]; + AudioMixingRule audioMixingRule = updatedMixingRules[i]; + mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent( + mix -> mix.setAudioMixingRule(audioMixingRule)); + } + } + return ret; + } + } + } + int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) { final Integer Uid = new Integer(uid); if (mUidDeviceAffinities.remove(Uid) != null) { @@ -13077,12 +13152,25 @@ public class AudioService extends IAudioService.Stub private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio"; - private Set<Integer> getAudioHalPids() { + private void getAudioAidlHalPids(HashSet<Integer> pids) { + try { + ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo(); + if (infos == null) return; + for (ServiceDebugInfo info : infos) { + if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) { + pids.add(info.debugPid); + } + } + } catch (RuntimeException e) { + // ignored, pid hashset does not change + } + } + + private void getAudioHalHidlPids(HashSet<Integer> pids) { try { IServiceManager serviceManager = IServiceManager.getService(); ArrayList<IServiceManager.InstanceDebugInfo> dump = serviceManager.debugDump(); - HashSet<Integer> pids = new HashSet<>(); for (IServiceManager.InstanceDebugInfo info : dump) { if (info.pid != IServiceManager.PidConstant.NO_PID && info.interfaceName != null @@ -13090,12 +13178,18 @@ public class AudioService extends IAudioService.Stub pids.add(info.pid); } } - return pids; } catch (RemoteException | RuntimeException e) { - return new HashSet<Integer>(); + // ignored, pid hashset does not change } } + private Set<Integer> getAudioHalPids() { + HashSet<Integer> pids = new HashSet<>(); + getAudioAidlHalPids(pids); + getAudioHalHidlPids(pids); + return pids; + } + private void updateAudioHalPids() { Set<Integer> pidsSet = getAudioHalPids(); if (pidsSet.isEmpty()) { diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index e70b6497538e..4f46dd13f973 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -26,6 +26,7 @@ import android.media.IDevicesForAttributesCallback; import android.media.ISoundDose; import android.media.ISoundDoseCallback; import android.media.audiopolicy.AudioMix; +import android.media.audiopolicy.AudioMixingRule; import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -601,6 +602,21 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, } /** + * Update already {@link AudioMixingRule}-s for already registered {@link AudioMix}-es. + * + * @param mixes - array of registered {@link AudioMix}-es to update. + * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to + * {@code mixesToUpdate} mixes. The array must be same size as + * {@code mixesToUpdate} and i-th {@link AudioMixingRule} must + * correspond to i-th {@link AudioMix} from mixesToUpdate array. + */ + public int updateMixingRules(@NonNull AudioMix[] mixes, + @NonNull AudioMixingRule[] updatedMixingRules) { + invalidateRoutingCache(); + return AudioSystem.updatePolicyMixes(mixes, updatedMixingRules); + } + + /** * Same as {@link AudioSystem#setUidDeviceAffinities(int, int[], String[])} * @param uid * @param types diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index 9fa569af316d..35260ed6f148 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -16,6 +16,8 @@ package com.android.server.audio; +import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES; +import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN; import static android.media.AudioSystem.isBluetoothDevice; import android.annotation.NonNull; @@ -682,8 +684,20 @@ public class SpatializerHelper { Log.i(TAG, "no spatialization device state found for Spatial Audio device:" + ada); return new Pair<>(false, false); } + boolean available = true; + if (isBluetoothDevice(deviceType)) { + // only checking headphones/binaural because external speakers cannot use transaural + // since their physical characteristics are unknown + if (deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_UNKNOWN + || deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES) { + available = (spatMode == SpatializationMode.SPATIALIZER_BINAURAL) + && mBinauralSupported; + } else { + available = false; + } + } // found the matching device state. - return new Pair<>(deviceState.isSAEnabled(), true /* available */); + return new Pair<>(deviceState.isSAEnabled(), available); } private synchronized void addWirelessDeviceIfNew(@NonNull AudioDeviceAttributes ada) { @@ -740,11 +754,36 @@ public class SpatializerHelper { } } + synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada) { + final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada); + if (isAvailableForAdiDeviceState(deviceState)) { + addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled()); + setHeadTrackerEnabled(deviceState.isHeadTrackerEnabled(), ada); + } else { + removeCompatibleAudioDevice(ada); + } + } + synchronized boolean isAvailableForDevice(@NonNull AudioDeviceAttributes ada) { if (ada.getRole() != AudioDeviceAttributes.ROLE_OUTPUT) { return false; } - return findSACompatibleDeviceStateForAudioDeviceAttributes(ada) != null; + + return isAvailableForAdiDeviceState( + findSACompatibleDeviceStateForAudioDeviceAttributes(ada)); + } + + private boolean isAvailableForAdiDeviceState(AdiDeviceState deviceState) { + if (deviceState == null) { + return false; + } + + if (isBluetoothDevice(deviceState.getInternalDeviceType()) + && deviceState.getAudioDeviceCategory() != AUDIO_DEVICE_CATEGORY_UNKNOWN + && deviceState.getAudioDeviceCategory() != AUDIO_DEVICE_CATEGORY_HEADPHONES) { + return false; + } + return true; } private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes, diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java index e8a20def02cb..fdf607d04ec7 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java @@ -98,6 +98,8 @@ public class AuthenticationStatsCollector { mAuthenticationStatsPersister.getAllFrrStats(mModality)) { mUserAuthenticationStatsMap.put(stats.getUserId(), stats); } + mAuthenticationStatsPersister.persistFrrThreshold(mThreshold); + mPersisterInitialized = true; } catch (IllegalStateException e) { Slog.w(TAG, "Failed to initialize AuthenticationStatsPersister.", e); diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsPersister.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsPersister.java index 8122b1d131f8..5625bfd21e76 100644 --- a/services/core/java/com/android/server/biometrics/AuthenticationStatsPersister.java +++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsPersister.java @@ -52,6 +52,7 @@ public class AuthenticationStatsPersister { private static final String FINGERPRINT_REJECTIONS = "fingerprint_rejections"; private static final String ENROLLMENT_NOTIFICATIONS = "enrollment_notifications"; private static final String KEY = "frr_stats"; + private static final String THRESHOLD_KEY = "frr_threshold"; @NonNull private final SharedPreferences mSharedPreferences; @@ -157,6 +158,13 @@ public class AuthenticationStatsPersister { } } + /** + * Persist frr threshold. + */ + public void persistFrrThreshold(float frrThreshold) { + mSharedPreferences.edit().putFloat(THRESHOLD_KEY, frrThreshold).apply(); + } + private Set<String> readFrrStats() { return mSharedPreferences.getStringSet(KEY, Set.of()); } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index ff35b192cccd..bfccd58b3f5d 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -3066,7 +3066,8 @@ public class Vpn { * <p>This variable controls the retry delay, and is reset when the VPN pass network * validation. */ - private int mValidationFailRetryCount = 0; + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + int mValidationFailRetryCount = 0; /** * The number of attempts since the last successful connection. @@ -3897,6 +3898,18 @@ public class Vpn { // Skip other invalid status if the scheduled recovery exists. if (mScheduledHandleDataStallFuture != null) return; + // Trigger network validation on the underlying network to possibly cause system + // switch default network or try recover if the current default network is broken. + // + // For the same underlying network, the first validation result should clarify if + // it's caused by broken underlying network. So only perform underlying network + // re-evaluation after first validation failure to prevent extra network resource + // costs on sending probes. + if (mValidationFailRetryCount == 0) { + mConnectivityManager.reportNetworkConnectivity( + mActiveNetwork, false /* hasConnectivity */); + } + if (mValidationFailRetryCount < MAX_MOBIKE_RECOVERY_ATTEMPT) { Log.d(TAG, "Validation failed"); diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java index 0d6635d5b6e4..2d763bc486bb 100644 --- a/services/core/java/com/android/server/display/ColorFade.java +++ b/services/core/java/com/android/server/display/ColorFade.java @@ -407,6 +407,12 @@ final class ColorFade { } } + void stop() { + if (mEglContext != null && mEglDisplay != null) { + EGL14.eglDestroyContext(mEglDisplay, mEglContext); + } + } + /** * Draws an animation frame showing the color fade activated at the * specified level. diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index c0c60a47263a..e3dafa4a4cc0 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -282,6 +282,8 @@ import javax.xml.datatype.DatatypeConfigurationException; * <screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease> * <screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease> * <screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease> + * <screenBrightnessRampSlowDecreaseIdle>0.05</screenBrightnessRampSlowDecreaseIdle> + * <screenBrightnessRampSlowIncreaseIdle>0.06</screenBrightnessRampSlowIncreaseIdle> * * <screenBrightnessRampIncreaseMaxMillis>2000</screenBrightnessRampIncreaseMaxMillis> * <screenBrightnessRampDecreaseMaxMillis>3000</screenBrightnessRampDecreaseMaxMillis> @@ -597,6 +599,8 @@ public class DisplayDeviceConfig { private float mBrightnessRampFastIncrease = Float.NaN; private float mBrightnessRampSlowDecrease = Float.NaN; private float mBrightnessRampSlowIncrease = Float.NaN; + private float mBrightnessRampSlowDecreaseIdle = Float.NaN; + private float mBrightnessRampSlowIncreaseIdle = Float.NaN; private long mBrightnessRampDecreaseMaxMillis = 0; private long mBrightnessRampIncreaseMaxMillis = 0; private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS; @@ -1039,6 +1043,14 @@ public class DisplayDeviceConfig { return mBrightnessRampSlowIncrease; } + public float getBrightnessRampSlowDecreaseIdle() { + return mBrightnessRampSlowDecreaseIdle; + } + + public float getBrightnessRampSlowIncreaseIdle() { + return mBrightnessRampSlowIncreaseIdle; + } + public long getBrightnessRampDecreaseMaxMillis() { return mBrightnessRampDecreaseMaxMillis; } @@ -1654,6 +1666,8 @@ public class DisplayDeviceConfig { + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease + ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease + + ", mBrightnessRampSlowDecreaseIdle=" + mBrightnessRampSlowDecreaseIdle + + ", mBrightnessRampSlowIncreaseIdle=" + mBrightnessRampSlowIncreaseIdle + ", mBrightnessRampDecreaseMaxMillis=" + mBrightnessRampDecreaseMaxMillis + ", mBrightnessRampIncreaseMaxMillis=" + mBrightnessRampIncreaseMaxMillis + "\n" @@ -1845,6 +1859,8 @@ public class DisplayDeviceConfig { mBrightnessRampFastIncrease = PowerManager.BRIGHTNESS_MAX; mBrightnessRampSlowDecrease = PowerManager.BRIGHTNESS_MAX; mBrightnessRampSlowIncrease = PowerManager.BRIGHTNESS_MAX; + mBrightnessRampSlowDecreaseIdle = PowerManager.BRIGHTNESS_MAX; + mBrightnessRampSlowIncreaseIdle = PowerManager.BRIGHTNESS_MAX; mBrightnessRampDecreaseMaxMillis = 0; mBrightnessRampIncreaseMaxMillis = 0; setSimpleMappingStrategyValues(); @@ -2665,6 +2681,12 @@ public class DisplayDeviceConfig { } private void loadBrightnessRamps(DisplayConfiguration config) { + // Interactive must come first, since idle falls back to it when values are unspecified. + loadBrightnessRampsInteractive(config); + loadBrightnessRampsIdle(config); + } + + private void loadBrightnessRampsInteractive(DisplayConfiguration config) { // Priority 1: Value in the display device config (float) // Priority 2: Value in the config.xml (int) final BigDecimal fastDownDecimal = config.getScreenBrightnessRampFastDecrease(); @@ -2697,6 +2719,27 @@ public class DisplayDeviceConfig { } } + private void loadBrightnessRampsIdle(DisplayConfiguration config) { + // Priority 1: Idle value in the display device config (float) + // Priority 2: Fallback - Interactive value from wherever. + final BigDecimal slowDownDecimalIdle = config.getScreenBrightnessRampSlowDecreaseIdle(); + final BigDecimal slowUpDecimalIdle = config.getScreenBrightnessRampSlowIncreaseIdle(); + + if (slowDownDecimalIdle != null && slowUpDecimalIdle != null) { + mBrightnessRampSlowDecreaseIdle = slowDownDecimalIdle.floatValue(); + mBrightnessRampSlowIncreaseIdle = slowUpDecimalIdle.floatValue(); + } else { + if (slowDownDecimalIdle != null || slowUpDecimalIdle != null) { + Slog.w(TAG, "Per display idle brightness ramp values ignored because not all " + + "values are present in display device config"); + } + // If these values don't exist, fall back to interactive mode values, since + // there are no idle ramp values in config.xml + mBrightnessRampSlowDecreaseIdle = mBrightnessRampSlowDecrease; + mBrightnessRampSlowIncreaseIdle = mBrightnessRampSlowIncrease; + } + } + private void loadBrightnessRampsFromConfigXml() { mBrightnessRampFastIncrease = BrightnessSynchronizer.brightnessIntToFloat( mContext.getResources().getInteger(R.integer.config_brightness_ramp_rate_fast)); diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index b994105de406..f3ad4b443ba3 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -472,6 +472,8 @@ public final class DisplayManagerService extends SystemService { private SensorManager mSensorManager; private BrightnessTracker mBrightnessTracker; + private SmallAreaDetectionController mSmallAreaDetectionController; + // Whether minimal post processing is allowed by the user. @GuardedBy("mSyncRoot") @@ -738,6 +740,8 @@ public final class DisplayManagerService extends SystemService { filter.addAction(Intent.ACTION_DOCK_EVENT); mContext.registerReceiver(mIdleModeReceiver, filter); + + mSmallAreaDetectionController = SmallAreaDetectionController.create(mContext); } @VisibleForTesting @@ -3128,6 +3132,9 @@ public final class DisplayManagerService extends SystemService { pw.println(); mDisplayModeDirector.dump(pw); mBrightnessSynchronizer.dump(pw); + if (mSmallAreaDetectionController != null) { + mSmallAreaDetectionController.dump(pw); + } } private static float[] getFloatArray(TypedArray array) { diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 79b73430b934..40dbabf29807 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -430,6 +430,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private float mBrightnessRampRateFastIncrease; private float mBrightnessRampRateSlowDecrease; private float mBrightnessRampRateSlowIncrease; + private float mBrightnessRampRateSlowDecreaseIdle; + private float mBrightnessRampRateSlowIncreaseIdle; // Report HBM brightness change to StatsD private int mDisplayStatsId; @@ -1312,6 +1314,10 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease(); mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease(); mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease(); + mBrightnessRampRateSlowDecreaseIdle = + mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(); + mBrightnessRampRateSlowIncreaseIdle = + mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(); mBrightnessRampDecreaseMaxTimeMillis = mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(); mBrightnessRampIncreaseMaxTimeMillis = @@ -1922,12 +1928,16 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } else { boolean isIncreasing = animateValue > currentBrightness; final float rampSpeed; + final boolean idle = mAutomaticBrightnessController != null + && mAutomaticBrightnessController.isInIdleMode(); if (isIncreasing && slowChange) { - rampSpeed = mBrightnessRampRateSlowIncrease; + rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle + : mBrightnessRampRateSlowIncrease; } else if (isIncreasing && !slowChange) { rampSpeed = mBrightnessRampRateFastIncrease; } else if (!isIncreasing && slowChange) { - rampSpeed = mBrightnessRampRateSlowDecrease; + rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle + : mBrightnessRampRateSlowDecrease; } else { rampSpeed = mBrightnessRampRateFastDecrease; } @@ -3526,7 +3536,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) { - return new DisplayPowerState(blanker, colorFade, displayId, displayState); + return new DisplayPowerState(blanker, colorFade, displayId, displayState, + new Handler(/*async=*/ true)); } DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps, diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java index 6c2240becbff..051c88690713 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController2.java +++ b/services/core/java/com/android/server/display/DisplayPowerController2.java @@ -319,8 +319,6 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal // Must only be accessed on the handler thread. private DisplayPowerState mPowerState; - - // The currently active screen on unblocker. This field is non-null whenever // we are waiting for a callback to release it and unblock the screen. private ScreenOnUnblocker mPendingScreenOnUnblocker; @@ -357,6 +355,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal private float mBrightnessRampRateFastIncrease; private float mBrightnessRampRateSlowDecrease; private float mBrightnessRampRateSlowIncrease; + private float mBrightnessRampRateSlowDecreaseIdle; + private float mBrightnessRampRateSlowIncreaseIdle; // Report HBM brightness change to StatsD private int mDisplayStatsId; @@ -1127,6 +1127,10 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease(); mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease(); mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease(); + mBrightnessRampRateSlowDecreaseIdle = + mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle(); + mBrightnessRampRateSlowIncreaseIdle = + mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle(); mBrightnessRampDecreaseMaxTimeMillis = mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(); mBrightnessRampIncreaseMaxTimeMillis = @@ -1535,12 +1539,16 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal } else { boolean isIncreasing = animateValue > currentBrightness; final float rampSpeed; + final boolean idle = mAutomaticBrightnessController != null + && mAutomaticBrightnessController.isInIdleMode(); if (isIncreasing && slowChange) { - rampSpeed = mBrightnessRampRateSlowIncrease; + rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle + : mBrightnessRampRateSlowIncrease; } else if (isIncreasing && !slowChange) { rampSpeed = mBrightnessRampRateFastIncrease; } else if (!isIncreasing && slowChange) { - rampSpeed = mBrightnessRampRateSlowDecrease; + rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle + : mBrightnessRampRateSlowDecrease; } else { rampSpeed = mBrightnessRampRateFastDecrease; } @@ -2861,7 +2869,8 @@ final class DisplayPowerController2 implements AutomaticBrightnessController.Cal DisplayPowerState getDisplayPowerState(DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) { - return new DisplayPowerState(blanker, colorFade, displayId, displayState); + return new DisplayPowerState(blanker, colorFade, displayId, displayState, + new Handler(/*async=*/ true)); } DualRampAnimator<DisplayPowerState> getDualRampAnimator(DisplayPowerState dps, diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index 2c257a17af91..85c6a6de860f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -74,8 +74,9 @@ final class DisplayPowerState { private volatile boolean mStopped; DisplayPowerState( - DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState) { - mHandler = new Handler(true /*async*/); + DisplayBlanker blanker, ColorFade colorFade, int displayId, int displayState, + Handler handler) { + mHandler = handler; mChoreographer = Choreographer.getInstance(); mBlanker = blanker; mColorFade = colorFade; @@ -317,6 +318,7 @@ final class DisplayPowerState { mStopped = true; mPhotonicModulator.interrupt(); dismissColorFade(); + stopColorFade(); mCleanListener = null; mHandler.removeCallbacksAndMessages(null); } @@ -376,6 +378,11 @@ final class DisplayPowerState { } } + // Clears up color fade resources. + private void stopColorFade() { + if (mColorFade != null) mColorFade.stop(); + } + private final Runnable mScreenUpdateRunnable = new Runnable() { @Override public void run() { diff --git a/services/core/java/com/android/server/display/SmallAreaDetectionController.java b/services/core/java/com/android/server/display/SmallAreaDetectionController.java new file mode 100644 index 000000000000..adaa5390cb9b --- /dev/null +++ b/services/core/java/com/android/server/display/SmallAreaDetectionController.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManagerInternal; +import android.provider.DeviceConfig; +import android.provider.DeviceConfigInterface; +import android.util.ArrayMap; +import android.util.SparseArray; + +import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; +import com.android.server.LocalServices; +import com.android.server.pm.UserManagerInternal; + +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Map; + +final class SmallAreaDetectionController { + private static native void nativeUpdateSmallAreaDetection(int[] uids, float[] thresholds); + private static native void nativeSetSmallAreaDetectionThreshold(int uid, float threshold); + + // TODO(b/281720315): Move this to DeviceConfig once server side ready. + private static final String KEY_SMALL_AREA_DETECTION_ALLOWLIST = + "small_area_detection_allowlist"; + + private final Object mLock = new Object(); + private final Context mContext; + private final PackageManagerInternal mPackageManager; + private final UserManagerInternal mUserManager; + @GuardedBy("mLock") + private final Map<String, Float> mAllowPkgMap = new ArrayMap<>(); + // TODO(b/298722189): Update allowlist when user changes + @GuardedBy("mLock") + private int[] mUserIds; + + static SmallAreaDetectionController create(@NonNull Context context) { + final SmallAreaDetectionController controller = + new SmallAreaDetectionController(context, DeviceConfigInterface.REAL); + final String property = DeviceConfigInterface.REAL.getProperty( + DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_SMALL_AREA_DETECTION_ALLOWLIST); + controller.updateAllowlist(property); + return controller; + } + + @VisibleForTesting + SmallAreaDetectionController(Context context, DeviceConfigInterface deviceConfig) { + mContext = context; + mPackageManager = LocalServices.getService(PackageManagerInternal.class); + mUserManager = LocalServices.getService(UserManagerInternal.class); + deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + BackgroundThread.getExecutor(), + new SmallAreaDetectionController.OnPropertiesChangedListener()); + mPackageManager.getPackageList(new PackageReceiver()); + } + + @VisibleForTesting + void updateAllowlist(@Nullable String property) { + synchronized (mLock) { + mAllowPkgMap.clear(); + if (property != null) { + final String[] mapStrings = property.split(","); + for (String mapString : mapStrings) putToAllowlist(mapString); + } else { + final String[] defaultMapStrings = mContext.getResources() + .getStringArray(R.array.config_smallAreaDetectionAllowlist); + for (String defaultMapString : defaultMapStrings) putToAllowlist(defaultMapString); + } + updateSmallAreaDetection(); + } + } + + @GuardedBy("mLock") + private void putToAllowlist(String rowData) { + // Data format: package:threshold - e.g. "com.abc.music:0.05" + final String[] items = rowData.split(":"); + if (items.length == 2) { + try { + final String pkg = items[0]; + final float threshold = Float.valueOf(items[1]); + mAllowPkgMap.put(pkg, threshold); + } catch (Exception e) { + // Just skip if items[1] - the threshold is not parsable number + } + } + } + + @GuardedBy("mLock") + private void updateUidListForAllUsers(SparseArray<Float> list, String pkg, float threshold) { + for (int i = 0; i < mUserIds.length; i++) { + final int userId = mUserIds[i]; + final int uid = mPackageManager.getPackageUid(pkg, 0, userId); + if (uid > 0) list.put(uid, threshold); + } + } + + @GuardedBy("mLock") + private void updateSmallAreaDetection() { + if (mAllowPkgMap.isEmpty()) return; + + mUserIds = mUserManager.getUserIds(); + + final SparseArray<Float> uidThresholdList = new SparseArray<>(); + for (String pkg : mAllowPkgMap.keySet()) { + final float threshold = mAllowPkgMap.get(pkg); + updateUidListForAllUsers(uidThresholdList, pkg, threshold); + } + + final int[] uids = new int[uidThresholdList.size()]; + final float[] thresholds = new float[uidThresholdList.size()]; + for (int i = 0; i < uidThresholdList.size(); i++) { + uids[i] = uidThresholdList.keyAt(i); + thresholds[i] = uidThresholdList.valueAt(i); + } + updateSmallAreaDetection(uids, thresholds); + } + + @VisibleForTesting + void updateSmallAreaDetection(int[] uids, float[] thresholds) { + nativeUpdateSmallAreaDetection(uids, thresholds); + } + + void setSmallAreaDetectionThreshold(int uid, float threshold) { + nativeSetSmallAreaDetectionThreshold(uid, threshold); + } + + void dump(PrintWriter pw) { + pw.println("Small area detection allowlist"); + pw.println(" Packages:"); + synchronized (mLock) { + for (String pkg : mAllowPkgMap.keySet()) { + pw.println(" " + pkg + " threshold = " + mAllowPkgMap.get(pkg)); + } + pw.println(" mUserIds=" + Arrays.toString(mUserIds)); + } + } + + private class OnPropertiesChangedListener implements DeviceConfig.OnPropertiesChangedListener { + public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { + if (properties.getKeyset().contains(KEY_SMALL_AREA_DETECTION_ALLOWLIST)) { + updateAllowlist( + properties.getString(KEY_SMALL_AREA_DETECTION_ALLOWLIST, null /*default*/)); + } + } + } + + private final class PackageReceiver implements PackageManagerInternal.PackageListObserver { + @Override + public void onPackageAdded(@NonNull String packageName, int uid) { + synchronized (mLock) { + if (mAllowPkgMap.containsKey(packageName)) { + setSmallAreaDetectionThreshold(uid, mAllowPkgMap.get(packageName)); + } + } + } + } +} diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1afa3ed97463..69b9e25b411c 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2677,7 +2677,7 @@ public class NotificationManagerService extends SystemService { mStatsManager.setPullAtomCallback( DND_MODE_RULE, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + ConcurrentUtils.DIRECT_EXECUTOR, mPullAtomCallback ); } diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 1cfc7d76919a..69a6c1357350 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -33,6 +33,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.MATCH_APEX; +import static android.content.pm.PackageManager.MATCH_ARCHIVED_PACKAGES; 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_DISABLED_COMPONENTS; @@ -1507,7 +1508,7 @@ public class ComputerEngine implements Computer { resolveExternalPackageName(p); return packageInfo; - } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 + } else if ((flags & (MATCH_UNINSTALLED_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0 && PackageUserStateUtils.isAvailable(state, flags)) { PackageInfo pi = new PackageInfo(); pi.packageName = ps.getPackageName(); @@ -1516,6 +1517,7 @@ public class ComputerEngine implements Computer { pi.sharedUserId = (sharedUser != null) ? sharedUser.getName() : null; pi.firstInstallTime = state.getFirstInstallTimeMillis(); pi.lastUpdateTime = ps.getLastUpdateTime(); + pi.isArchived = isArchived(state); ApplicationInfo ai = new ApplicationInfo(); ai.packageName = ps.getPackageName(); @@ -1614,7 +1616,7 @@ public class ComputerEngine implements Computer { return generatePackageInfo(ps, flags, userId); } - if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) { + if (!matchFactoryOnly && (flags & (MATCH_KNOWN_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0) { final PackageStateInternal ps = mSettings.getPackage(packageName); if (ps == null) return null; if (filterSharedLibPackage(ps, filterCallingUid, userId, flags)) { @@ -1678,9 +1680,11 @@ public class ComputerEngine implements Computer { final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; final boolean listApex = (flags & MATCH_APEX) != 0; final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0; + // Only list archived apps, not fully uninstalled ones. Other entries are unaffected. + final boolean listArchivedOnly = !listUninstalled && (flags & MATCH_ARCHIVED_PACKAGES) != 0; ArrayList<PackageInfo> list; - if (listUninstalled) { + if (listUninstalled || listArchivedOnly) { list = new ArrayList<>(mSettings.getPackages().size()); for (PackageStateInternal ps : mSettings.getPackages().values()) { if (listFactory) { @@ -1696,6 +1700,9 @@ public class ComputerEngine implements Computer { if (!listApex && ps.getPkg() != null && ps.getPkg().isApex()) { continue; } + if (listArchivedOnly && !isArchived(ps.getUserStateOrDefault(userId))) { + continue; + } if (filterSharedLibPackage(ps, callingUid, userId, flags)) { continue; } @@ -1739,6 +1746,13 @@ public class ComputerEngine implements Computer { return new ParceledListSlice<>(list); } + // TODO(b/288142708) Check for userState.isInstalled() here once this bug is fixed. + // If an app has isInstalled() == true - it should not be filtered above in any case, currently + // it is. + private static boolean isArchived(PackageUserStateInternal userState) { + return userState.getArchiveState() != null; + } + public final ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter, int sourceUserId, int targetUserId) { ResolveInfo forwardingResolveInfo = new ResolveInfo(); @@ -2612,7 +2626,7 @@ public class ComputerEngine implements Computer { return UserHandle.getUid(userId, p.getUid()); } } - if ((flags & MATCH_KNOWN_PACKAGES) != 0) { + if ((flags & (MATCH_KNOWN_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0) { final PackageStateInternal ps = mSettings.getPackage(packageName); if (ps != null && PackageStateUtils.isMatch(ps, flags) && !shouldFilterApplication(ps, callingUid, userId)) { @@ -3671,7 +3685,7 @@ public class ComputerEngine implements Computer { ps.getAppId())); } } - if ((flags & MATCH_KNOWN_PACKAGES) != 0) { + if ((flags & (MATCH_KNOWN_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0) { if (PackageStateUtils.isMatch(ps, flags) && !shouldFilterApplication(ps, callingUid, userId)) { return mPermissionManager.getGidsForUid( @@ -4525,7 +4539,8 @@ public class ComputerEngine implements Computer { flags = updateFlagsForPackage(flags, userId); enforceCrossUserPermission(Binder.getCallingUid(), userId, true /* requireFullPermission */, false /* checkShell */, "get packages holding permissions"); - final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0; + final boolean listUninstalled = + (flags & (MATCH_KNOWN_PACKAGES | MATCH_ARCHIVED_PACKAGES)) != 0; ArrayList<PackageInfo> list = new ArrayList<>(); boolean[] tmpBools = new boolean[permissions.length]; diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index f8313e7d18ff..dd043406f653 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -1144,8 +1144,16 @@ final class InstallPackageHelper { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); final ParsedPackage parsedPackage; try (PackageParser2 pp = mPm.mInjector.getPreparingPackageParser()) { - parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false); - AndroidPackageUtils.validatePackageDexMetadata(parsedPackage); + if (request.getPackageLite() == null || !PackageInstallerSession.isArchivedInstallation( + request.getInstallFlags())) { + // TODO: pass packageLite from install request instead of reparsing the package + parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false); + AndroidPackageUtils.validatePackageDexMetadata(parsedPackage); + } else { + // Archived install mode, no APK. + parsedPackage = pp.parsePackageFromPackageLite(request.getPackageLite(), + parseFlags); + } } catch (PackageManagerException e) { throw new PrepareFailure("Failed parse during installPackageLI", e); } finally { @@ -1547,6 +1555,7 @@ final class InstallPackageHelper { // TODO: Are these system flags actually set properly at this stage? boolean isUpdatedSystemAppInferred = pkgSetting != null && pkgSetting.isSystem(); + // derivePackageAbi works OK for archived packages despite logging some errors. final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi = mPackageAbiHelper.derivePackageAbi(parsedPackage, systemApp, (isUpdatedSystemAppFromExistingSetting diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java index 6c265314c0cc..fe7c0864d4d0 100644 --- a/services/core/java/com/android/server/pm/InstallRequest.java +++ b/services/core/java/com/android/server/pm/InstallRequest.java @@ -35,6 +35,7 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageManager; import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningDetails; +import android.content.pm.parsing.PackageLite; import android.net.Uri; import android.os.Build; import android.os.Process; @@ -93,6 +94,8 @@ final class InstallRequest { private int[] mNewUsers; @Nullable private AndroidPackage mPkg; + @Nullable + private PackageLite mPackageLite; private int mReturnCode; private int mInternalErrorCode; @Nullable @@ -142,6 +145,7 @@ final class InstallRequest { params.mInstallReason, params.mInstallScenario, params.mForceQueryableOverride, params.mDataLoaderType, params.mPackageSource, params.mApplicationEnabledSettingPersistent); + mPackageLite = params.mPackageLite; mPackageMetrics = new PackageMetrics(this); mIsInstallInherit = params.mIsInherit; mSessionId = params.mSessionId; @@ -306,6 +310,11 @@ final class InstallRequest { } @Nullable + public PackageLite getPackageLite() { + return mPackageLite; + } + + @Nullable public String getTraceMethod() { return mInstallArgs == null ? null : mInstallArgs.mTraceMethod; } diff --git a/services/core/java/com/android/server/pm/PackageArchiverService.java b/services/core/java/com/android/server/pm/PackageArchiverService.java index 9c31dc9a1215..29f49c874640 100644 --- a/services/core/java/com/android/server/pm/PackageArchiverService.java +++ b/services/core/java/com/android/server/pm/PackageArchiverService.java @@ -17,17 +17,26 @@ package com.android.server.pm; import static android.content.pm.PackageManager.DELETE_KEEP_DATA; +import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE; +import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; +import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.app.AppOpsManager; +import android.app.BroadcastOptions; import android.content.Context; +import android.content.Intent; import android.content.IntentSender; import android.content.pm.IPackageArchiverService; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; +import android.content.pm.PackageArchiver; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.os.Binder; +import android.os.Bundle; import android.os.ParcelableException; import android.os.UserHandle; import android.text.TextUtils; @@ -36,6 +45,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.server.pm.pkg.ArchiveState; import com.android.server.pm.pkg.ArchiveState.ArchiveActivityInfo; import com.android.server.pm.pkg.PackageStateInternal; +import com.android.server.pm.pkg.PackageUserStateInternal; import java.nio.file.Path; import java.util.ArrayList; @@ -51,7 +61,12 @@ import java.util.Objects; */ public class PackageArchiverService extends IPackageArchiverService.Stub { - private static final String TAG = "PackageArchiver"; + /** + * The maximum time granted for an app store to start a foreground service when unarchival + * is requested. + */ + // TODO(b/297358628) Make this configurable through a flag. + private static final int DEFAULT_UNARCHIVE_FOREGROUND_TIMEOUT_MS = 120 * 1000; private final Context mContext; private final PackageManagerService mPm; @@ -82,17 +97,14 @@ public class PackageArchiverService extends IPackageArchiverService.Stub { snapshot.enforceCrossUserPermission(binderUid, userId, true, true, "archiveApp"); verifyCaller(providedUid, binderUid); - PackageStateInternal ps = getPackageState(packageName, snapshot, binderUid, userId); - verifyInstaller(packageName, ps); - - // TODO(b/291569242) Verify that this list is not empty and return failure with - // intentsender - List<LauncherActivityInfo> mainActivities = getLauncherApps().getActivityList( - ps.getPackageName(), - new UserHandle(userId)); - - // TODO(b/282952870) Bug: should happen after the uninstall completes successfully - storeArchiveState(ps, mainActivities, userId); + ArchiveState archiveState; + try { + archiveState = createArchiveState(packageName, userId); + // TODO(b/282952870) Should be reverted if uninstall fails/cancels + storeArchiveState(packageName, archiveState, userId); + } catch (PackageManager.NameNotFoundException e) { + throw new ParcelableException(e); + } // TODO(b/278553670) Add special strings for the delete dialog mPm.mInstallerService.uninstall( @@ -100,25 +112,154 @@ public class PackageArchiverService extends IPackageArchiverService.Stub { callerPackageName, DELETE_KEEP_DATA, intentSender, userId); } - private static void verifyInstaller(String packageName, PackageStateInternal ps) { - if (ps.getInstallSource().mUpdateOwnerPackageName == null - && ps.getInstallSource().mInstallerPackageName == null) { + private ArchiveState createArchiveState(String packageName, int userId) + throws PackageManager.NameNotFoundException { + PackageStateInternal ps = getPackageState(packageName, mPm.snapshotComputer(), + Binder.getCallingUid(), userId); + String responsibleInstallerPackage = getResponsibleInstallerPackage(ps); + if (responsibleInstallerPackage == null) { + throw new PackageManager.NameNotFoundException( + TextUtils.formatSimple("No installer found to archive app %s.", + packageName)); + } + + List<LauncherActivityInfo> mainActivities = getLauncherActivityInfos(ps, userId); + List<ArchiveActivityInfo> archiveActivityInfos = new ArrayList<>(); + for (int i = 0; i < mainActivities.size(); i++) { + // TODO(b/278553670) Extract and store launcher icons + ArchiveActivityInfo activityInfo = new ArchiveActivityInfo( + mainActivities.get(i).getLabel().toString(), + Path.of("/TODO"), null); + archiveActivityInfos.add(activityInfo); + } + + return new ArchiveState(archiveActivityInfos, responsibleInstallerPackage); + } + + @Override + public void requestUnarchive( + @NonNull String packageName, + @NonNull String callerPackageName, + @NonNull UserHandle userHandle) { + Objects.requireNonNull(packageName); + Objects.requireNonNull(callerPackageName); + Objects.requireNonNull(userHandle); + + Computer snapshot = mPm.snapshotComputer(); + int userId = userHandle.getIdentifier(); + int binderUid = Binder.getCallingUid(); + int providedUid = snapshot.getPackageUid(callerPackageName, 0, userId); + snapshot.enforceCrossUserPermission(binderUid, userId, true, true, + "unarchiveApp"); + verifyCaller(providedUid, binderUid); + PackageStateInternal ps; + try { + ps = getPackageState(packageName, snapshot, binderUid, userId); + verifyArchived(ps, userId); + } catch (PackageManager.NameNotFoundException e) { + throw new ParcelableException(e); + } + String installerPackage = getResponsibleInstallerPackage(ps); + if (installerPackage == null) { throw new ParcelableException( new PackageManager.NameNotFoundException( - TextUtils.formatSimple("No installer found to archive app %s.", + TextUtils.formatSimple("No installer found to unarchive app %s.", packageName))); } + + mPm.mHandler.post(() -> unarchiveInternal(packageName, userHandle, installerPackage)); + } + + private void verifyArchived(PackageStateInternal ps, int userId) + throws PackageManager.NameNotFoundException { + PackageUserStateInternal userState = ps.getUserStateOrDefault(userId); + // TODO(b/288142708) Check for isInstalled false here too. + if (userState.getArchiveState() == null) { + throw new PackageManager.NameNotFoundException( + TextUtils.formatSimple("Package %s is not currently archived.", + ps.getPackageName())); + } + } + + @RequiresPermission( + allOf = { + Manifest.permission.INTERACT_ACROSS_USERS, + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, + android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}, + conditional = true) + private void unarchiveInternal(String packageName, UserHandle userHandle, + String installerPackage) { + int userId = userHandle.getIdentifier(); + Intent unarchiveIntent = new Intent(Intent.ACTION_UNARCHIVE_PACKAGE); + unarchiveIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + unarchiveIntent.putExtra(PackageArchiver.EXTRA_UNARCHIVE_PACKAGE_NAME, packageName); + unarchiveIntent.putExtra(PackageArchiver.EXTRA_UNARCHIVE_ALL_USERS, + userId == UserHandle.USER_ALL); + unarchiveIntent.setPackage(installerPackage); + + // If the unarchival is requested for all users, the current user is used for unarchival. + UserHandle userForUnarchival = userId == UserHandle.USER_ALL + ? UserHandle.of(mPm.mUserManager.getCurrentUserId()) + : userHandle; + mContext.sendOrderedBroadcastAsUser( + unarchiveIntent, + userForUnarchival, + /* receiverPermission = */ null, + AppOpsManager.OP_NONE, + createUnarchiveOptions(), + /* resultReceiver= */ null, + /* scheduler= */ null, + /* initialCode= */ 0, + /* initialData= */ null, + /* initialExtras= */ null); + } + + private List<LauncherActivityInfo> getLauncherActivityInfos(PackageStateInternal ps, + int userId) throws PackageManager.NameNotFoundException { + List<LauncherActivityInfo> mainActivities = + Binder.withCleanCallingIdentity(() -> getLauncherApps().getActivityList( + ps.getPackageName(), + new UserHandle(userId))); + if (mainActivities.isEmpty()) { + throw new PackageManager.NameNotFoundException( + TextUtils.formatSimple("The app %s does not have a main activity.", + ps.getPackageName())); + } + + return mainActivities; + } + + @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, + android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) + private Bundle createUnarchiveOptions() { + BroadcastOptions options = BroadcastOptions.makeBasic(); + options.setTemporaryAppAllowlist(getUnarchiveForegroundTimeout(), + TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + REASON_PACKAGE_UNARCHIVE, ""); + return options.toBundle(); + } + + private static int getUnarchiveForegroundTimeout() { + return DEFAULT_UNARCHIVE_FOREGROUND_TIMEOUT_MS; + } + + private String getResponsibleInstallerPackage(PackageStateInternal ps) { + return ps.getInstallSource().mUpdateOwnerPackageName == null + ? ps.getInstallSource().mInstallerPackageName + : ps.getInstallSource().mUpdateOwnerPackageName; } @NonNull private static PackageStateInternal getPackageState(String packageName, - Computer snapshot, int callingUid, int userId) { + Computer snapshot, int callingUid, int userId) + throws PackageManager.NameNotFoundException { PackageStateInternal ps = snapshot.getPackageStateFiltered(packageName, callingUid, userId); if (ps == null) { - throw new ParcelableException( - new PackageManager.NameNotFoundException( - TextUtils.formatSimple("Package %s not found.", packageName))); + throw new PackageManager.NameNotFoundException( + TextUtils.formatSimple("Package %s not found.", packageName)); } return ps; } @@ -130,38 +271,25 @@ public class PackageArchiverService extends IPackageArchiverService.Stub { return mLauncherApps; } - private void storeArchiveState(PackageStateInternal ps, - List<LauncherActivityInfo> mainActivities, int userId) { - List<ArchiveActivityInfo> activityInfos = new ArrayList<>(); - for (int i = 0; i < mainActivities.size(); i++) { - // TODO(b/278553670) Extract and store launcher icons - ArchiveActivityInfo activityInfo = new ArchiveActivityInfo( - mainActivities.get(i).getLabel().toString(), - Path.of("/TODO"), null); - activityInfos.add(activityInfo); - } - - InstallSource installSource = ps.getInstallSource(); - String installerPackageName = installSource.mUpdateOwnerPackageName != null - ? installSource.mUpdateOwnerPackageName : installSource.mInstallerPackageName; - + private void storeArchiveState(String packageName, ArchiveState archiveState, int userId) + throws PackageManager.NameNotFoundException { synchronized (mPm.mLock) { - PackageSetting packageSetting = getPackageSettingLocked(ps.getPackageName(), userId); + PackageSetting packageSetting = getPackageSettingLocked(packageName, userId); packageSetting .modifyUserState(userId) - .setArchiveState(new ArchiveState(activityInfos, installerPackageName)); + .setArchiveState(archiveState); } } @NonNull @GuardedBy("mPm.mLock") - private PackageSetting getPackageSettingLocked(String packageName, int userId) { + private PackageSetting getPackageSettingLocked(String packageName, int userId) + throws PackageManager.NameNotFoundException { PackageSetting ps = mPm.mSettings.getPackageLPr(packageName); // Shouldn't happen, we already verify presence of the package in getPackageState() if (ps == null || !ps.getUserStateOrDefault(userId).isInstalled()) { - throw new ParcelableException( - new PackageManager.NameNotFoundException( - TextUtils.formatSimple("Package %s not found.", packageName))); + throw new PackageManager.NameNotFoundException( + TextUtils.formatSimple("Package %s not found.", packageName)); } return ps; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java new file mode 100644 index 000000000000..d40a7157253b --- /dev/null +++ b/services/core/java/com/android/server/pm/PackageInstallerHistoricalSession.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.pm; + +import android.content.pm.PackageInstaller.PreapprovalDetails; +import android.content.pm.PackageInstaller.SessionInfo; +import android.content.pm.PackageInstaller.SessionParams; + +import com.android.internal.util.IndentingPrintWriter; + +import java.io.CharArrayWriter; +import java.io.File; + +/** + * A historical session object that stores minimal session info. + */ +public final class PackageInstallerHistoricalSession { + public final int sessionId; + public final int userId; + private final String mParams; + private final long mCreatedMillis; + + private final File mStageDir; + private final String mStageCid; + + private final long mUpdatedMillis; + + private final long mCommittedMillis; + + private final int mOriginalInstallerUid; + + private final String mOriginalInstallerPackageName; + + private final int mInstallerUid; + + private final InstallSource mInstallSource; + + private final float mClientProgress; + + private final float mProgress; + private final boolean mSealed; + + private final boolean mPreapprovalRequested; + private final boolean mCommitted; + + private final boolean mStageDirInUse; + + private final boolean mPermissionsManuallyAccepted; + + private final int mFinalStatus; + private final String mFinalMessage; + + private final int mFds; + private final int mBridges; + + private final String mPreapprovalDetails; + private final int mParentSessionId; + private final boolean mDestroyed; + private final int[] mChildSessionIds; + private final boolean mSessionApplied; + private final boolean mSessionReady; + private final boolean mSessionFailed; + private final int mSessionErrorCode; + private final String mSessionErrorMessage; + + PackageInstallerHistoricalSession(int sessionId, int userId, int originalInstallerUid, + String originalInstallerPackageName, InstallSource installSource, int installerUid, + long createdMillis, long updatedMillis, long committedMillis, File stageDir, + String stageCid, float clientProgress, float progress, boolean committed, + boolean preapprovalRequested, boolean sealed, boolean permissionsManuallyAccepted, + boolean stageDirInUse, boolean destroyed, int fds, int bridges, int finalStatus, + String finalMessage, SessionParams params, int parentSessionId, + int[] childSessionIds, boolean sessionApplied, boolean sessionFailed, + boolean sessionReady, int sessionErrorCode, String sessionErrorMessage, + PreapprovalDetails preapprovalDetails) { + this.sessionId = sessionId; + this.userId = userId; + this.mOriginalInstallerUid = originalInstallerUid; + this.mOriginalInstallerPackageName = originalInstallerPackageName; + this.mInstallSource = installSource; + this.mInstallerUid = installerUid; + this.mCreatedMillis = createdMillis; + this.mUpdatedMillis = updatedMillis; + this.mCommittedMillis = committedMillis; + this.mStageDir = stageDir; + this.mStageCid = stageCid; + this.mClientProgress = clientProgress; + this.mProgress = progress; + this.mCommitted = committed; + this.mPreapprovalRequested = preapprovalRequested; + this.mSealed = sealed; + this.mPermissionsManuallyAccepted = permissionsManuallyAccepted; + this.mStageDirInUse = stageDirInUse; + this.mDestroyed = destroyed; + this.mFds = fds; + this.mBridges = bridges; + this.mFinalStatus = finalStatus; + this.mFinalMessage = finalMessage; + + CharArrayWriter writer = new CharArrayWriter(); + IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); + params.dump(pw); + this.mParams = writer.toString(); + + this.mParentSessionId = parentSessionId; + this.mChildSessionIds = childSessionIds; + this.mSessionApplied = sessionApplied; + this.mSessionFailed = sessionFailed; + this.mSessionReady = sessionReady; + this.mSessionErrorCode = sessionErrorCode; + this.mSessionErrorMessage = sessionErrorMessage; + if (preapprovalDetails != null) { + this.mPreapprovalDetails = preapprovalDetails.toString(); + } else { + this.mPreapprovalDetails = null; + } + } + + void dump(IndentingPrintWriter pw) { + pw.println("Session " + sessionId + ":"); + pw.increaseIndent(); + + pw.printPair("userId", userId); + pw.printPair("mOriginalInstallerUid", mOriginalInstallerUid); + pw.printPair("mOriginalInstallerPackageName", mOriginalInstallerPackageName); + pw.printPair("installerPackageName", mInstallSource.mInstallerPackageName); + pw.printPair("installInitiatingPackageName", mInstallSource.mInitiatingPackageName); + pw.printPair("installOriginatingPackageName", mInstallSource.mOriginatingPackageName); + pw.printPair("mInstallerUid", mInstallerUid); + pw.printPair("createdMillis", mCreatedMillis); + pw.printPair("updatedMillis", mUpdatedMillis); + pw.printPair("committedMillis", mCommittedMillis); + pw.printPair("stageDir", mStageDir); + pw.printPair("stageCid", mStageCid); + pw.println(); + + pw.print(mParams); + + pw.printPair("mClientProgress", mClientProgress); + pw.printPair("mProgress", mProgress); + pw.printPair("mCommitted", mCommitted); + pw.printPair("mPreapprovalRequested", mPreapprovalRequested); + pw.printPair("mSealed", mSealed); + pw.printPair("mPermissionsManuallyAccepted", mPermissionsManuallyAccepted); + pw.printPair("mStageDirInUse", mStageDirInUse); + pw.printPair("mDestroyed", mDestroyed); + pw.printPair("mFds", mFds); + pw.printPair("mBridges", mBridges); + pw.printPair("mFinalStatus", mFinalStatus); + pw.printPair("mFinalMessage", mFinalMessage); + pw.printPair("mParentSessionId", mParentSessionId); + pw.printPair("mChildSessionIds", mChildSessionIds); + pw.printPair("mSessionApplied", mSessionApplied); + pw.printPair("mSessionFailed", mSessionFailed); + pw.printPair("mSessionReady", mSessionReady); + pw.printPair("mSessionErrorCode", mSessionErrorCode); + pw.printPair("mSessionErrorMessage", mSessionErrorMessage); + pw.printPair("mPreapprovalDetails", mPreapprovalDetails); + pw.println(); + + pw.decreaseIndent(); + } + + /** + * Generates a {@link SessionInfo} object. + */ + public SessionInfo generateInfo() { + final SessionInfo info = new SessionInfo(); + info.sessionId = sessionId; + info.userId = userId; + info.installerPackageName = mInstallSource.mInstallerPackageName; + info.installerAttributionTag = mInstallSource.mInstallerAttributionTag; + info.progress = mProgress; + info.sealed = mSealed; + info.isCommitted = mCommitted; + info.isPreapprovalRequested = mPreapprovalRequested; + + info.parentSessionId = mParentSessionId; + info.childSessionIds = mChildSessionIds; + info.isSessionApplied = mSessionApplied; + info.isSessionReady = mSessionReady; + info.isSessionFailed = mSessionFailed; + info.setSessionErrorCode(mSessionErrorCode, mSessionErrorMessage); + info.createdMillis = mCreatedMillis; + info.updatedMillis = mUpdatedMillis; + info.installerUid = mInstallerUid; + return info; + } +} diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 10cd51a717cb..e3602565ef5b 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -111,7 +111,6 @@ import libcore.io.IoUtils; import org.xmlpull.v1.XmlPullParserException; -import java.io.CharArrayWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -230,7 +229,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements /** Historical sessions kept around for debugging purposes */ @GuardedBy("mSessions") - private final List<String> mHistoricalSessions = new ArrayList<>(); + private final List<PackageInstallerHistoricalSession> mHistoricalSessions = new ArrayList<>(); @GuardedBy("mSessions") private final SparseIntArray mHistoricalSessionsByInstaller = new SparseIntArray(); @@ -570,14 +569,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements @GuardedBy("mSessions") private void addHistoricalSessionLocked(PackageInstallerSession session) { - CharArrayWriter writer = new CharArrayWriter(); - IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); - session.dump(pw); if (mHistoricalSessions.size() > HISTORICAL_SESSIONS_THRESHOLD) { Slog.d(TAG, "Historical sessions size reaches threshold, clear the oldest"); mHistoricalSessions.subList(0, HISTORICAL_CLEAR_SIZE).clear(); } - mHistoricalSessions.add(writer.toString()); + mHistoricalSessions.add(session.createHistoricalSession()); int installerUid = session.getInstallerUid(); // Increment the number of sessions by this installerUid. @@ -1223,6 +1219,24 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements return new ParceledListSlice<>(result); } + ParceledListSlice<SessionInfo> getHistoricalSessions(int userId) { + final int callingUid = Binder.getCallingUid(); + final Computer snapshot = mPm.snapshotComputer(); + snapshot.enforceCrossUserPermission(callingUid, userId, true, false, "getAllSessions"); + + final List<SessionInfo> result = new ArrayList<>(); + synchronized (mSessions) { + for (int i = 0; i < mHistoricalSessions.size(); i++) { + final PackageInstallerHistoricalSession session = mHistoricalSessions.get(i); + if (userId == UserHandle.USER_ALL || session.userId == userId) { + result.add(session.generateInfo()); + } + } + } + result.removeIf(info -> shouldFilterSession(snapshot, callingUid, info)); + return new ParceledListSlice<>(result); + } + @Override public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags, IntentSender statusReceiver, int userId) { @@ -1837,7 +1851,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements pw.increaseIndent(); N = mHistoricalSessions.size(); for (int i = 0; i < N; i++) { - pw.print(mHistoricalSessions.get(i)); + mHistoricalSessions.get(i).dump(pw); pw.println(); } pw.println(); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 923bbab42ab3..1bdade2df6dc 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -31,6 +31,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; import static android.content.pm.PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT; import static android.content.pm.PackageManager.INSTALL_FAILED_PRE_APPROVAL_NOT_AVAILABLE; +import static android.content.pm.PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES; import static android.content.pm.PackageManager.INSTALL_STAGED; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; @@ -52,6 +53,7 @@ import static com.android.internal.util.XmlUtils.writeUriAttribute; import static com.android.server.pm.PackageInstallerService.prepareStageDir; import static com.android.server.pm.PackageManagerService.APP_METADATA_FILE_NAME; import static com.android.server.pm.PackageManagerServiceUtils.isInstalledByAdb; +import static com.android.server.pm.PackageManagerShellCommandDataLoader.Metadata; import android.Manifest; import android.annotation.AnyThread; @@ -838,6 +840,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { params.dataLoaderParams.getComponentName().getPackageName()); } + static boolean isArchivedInstallation(int installFlags) { + return (installFlags & PackageManager.INSTALL_ARCHIVED) != 0; + } + private final Handler.Callback mHandlerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { @@ -896,6 +902,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return isSystemDataLoaderInstallation(this.params); } + private boolean isArchivedInstallation() { + return isArchivedInstallation(this.params.installFlags); + } + /** * @return {@code true} iff the installing is app an device owner or affiliated profile owner. */ @@ -1146,6 +1156,36 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (isIncrementalInstallation() && !IncrementalManager.isAllowed()) { throw new IllegalArgumentException("Incremental installation not allowed."); } + + if (isArchivedInstallation()) { + if (params.mode != SessionParams.MODE_FULL_INSTALL) { + throw new IllegalArgumentException( + "Archived installation can only be full install."); + } + if (!isStreamingInstallation() || !isSystemDataLoaderInstallation()) { + throw new IllegalArgumentException( + "Archived installation can only use Streaming System DataLoader."); + } + } + } + + PackageInstallerHistoricalSession createHistoricalSession() { + final float progress; + final float clientProgress; + synchronized (mProgressLock) { + progress = mProgress; + clientProgress = mClientProgress; + } + synchronized (mLock) { + return new PackageInstallerHistoricalSession(sessionId, userId, mOriginalInstallerUid, + mOriginalInstallerPackageName, mInstallSource, mInstallerUid, createdMillis, + updatedMillis, committedMillis, stageDir, stageCid, clientProgress, progress, + isCommitted(), isPreapprovalRequested(), mSealed, mPermissionsManuallyAccepted, + mStageDirInUse, mDestroyed, mFds.size(), mBridges.size(), mFinalStatus, + mFinalMessage, params, mParentSessionId, getChildSessionIdsLocked(), + mSessionApplied, mSessionFailed, mSessionReady, mSessionErrorCode, + mSessionErrorMessage, mPreapprovalDetails); + } } /** @@ -1462,6 +1502,58 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @GuardedBy("mLock") + private List<ApkLite> getAddedApkLitesLocked() throws PackageManagerException { + if (!isArchivedInstallation()) { + List<File> files = getAddedApksLocked(); + final List<ApkLite> result = new ArrayList<>(files.size()); + + final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); + for (int i = 0, size = files.size(); i < size; ++i) { + final ParseResult<ApkLite> parseResult = ApkLiteParseUtils.parseApkLite( + input.reset(), files.get(i), + ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES); + if (parseResult.isError()) { + throw new PackageManagerException(parseResult.getErrorCode(), + parseResult.getErrorMessage(), parseResult.getException()); + } + result.add(parseResult.getResult()); + } + + return result; + } + + InstallationFile[] files = getInstallationFilesLocked(); + final List<ApkLite> result = new ArrayList<>(files.length); + + for (int i = 0, size = files.length; i < size; ++i) { + File file = new File(stageDir, files[i].getName()); + if (!sAddedApkFilter.accept(file)) { + continue; + } + + final Metadata metadata; + try { + metadata = Metadata.fromByteArray(files[i].getMetadata()); + } catch (IOException e) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Failed to ", e); + } + if (metadata.getMode() != Metadata.ARCHIVED) { + throw new PackageManagerException(INSTALL_FAILED_VERIFICATION_FAILURE, + "File metadata is not for ARCHIVED package: " + file); + } + + var archPkg = metadata.getArchivedPackage(); + if (archPkg.packageName == null || archPkg.signingDetails == null) { + throw new PackageManagerException(INSTALL_FAILED_VERIFICATION_FAILURE, + "ArchivedPackage does not contain required info: " + file); + } + result.add(new ApkLite(file.getAbsolutePath(), archPkg)); + } + return result; + } + + @GuardedBy("mLock") private List<File> getRemovedFilesLocked() { String[] names = getNamesLocked(); return filterFiles(stageDir, names, sRemovedFilter); @@ -2732,9 +2824,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed"); } - Objects.requireNonNull(mPackageName); - Objects.requireNonNull(mSigningDetails); - Objects.requireNonNull(mResolvedBaseFile); + if (mPackageName == null) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Session no package name"); + } + if (mSigningDetails == null) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Session no signing data"); + } + if (mResolvedBaseFile == null) { + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, + "Session no resolved base file"); + } final PackageLite result; if (!isApexSession()) { // For mode inherit existing, it would link/copy existing files to stage dir in @@ -3176,7 +3277,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - final List<File> addedFiles = getAddedApksLocked(); + final List<ApkLite> addedFiles = getAddedApkLitesLocked(); if (addedFiles.isEmpty() && (removeSplitList.size() == 0 || getStagedAppMetadataFile() != null)) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, @@ -3190,15 +3291,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final ArraySet<String> requiredSplitTypes = new ArraySet<>(); final ArrayMap<String, ApkLite> splitApks = new ArrayMap<>(); final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); - for (File addedFile : addedFiles) { - final ParseResult<ApkLite> result = ApkLiteParseUtils.parseApkLite(input.reset(), - addedFile, ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES); - if (result.isError()) { - throw new PackageManagerException(result.getErrorCode(), - result.getErrorMessage(), result.getException()); - } - - final ApkLite apk = result.getResult(); + for (ApkLite apk : addedFiles) { if (!stagedSplits.add(apk.getSplitName())) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "Split " + apk.getSplitName() + " was defined multiple times"); @@ -3214,7 +3307,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } mHasDeviceAdminReceiver = apk.isHasDeviceAdminReceiver(); - assertApkConsistentLocked(String.valueOf(addedFile), apk); + assertApkConsistentLocked(String.valueOf(apk), apk); // Take this opportunity to enforce uniform naming final String targetName = ApkLiteParseUtils.splitNameToFileName(apk); @@ -3235,7 +3328,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } final File targetFile = new File(stageDir, targetName); - resolveAndStageFileLocked(addedFile, targetFile, apk.getSplitName()); + if (!isArchivedInstallation()) { + final File sourceFile = new File(apk.getPath()); + resolveAndStageFileLocked(sourceFile, targetFile, apk.getSplitName()); + } // Base is coming from session if (apk.getSplitName() == null) { @@ -4005,6 +4101,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true); } + // Skip native libraries processing for archival installation. + if (isArchivedInstallation()) { + return; + } + NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(packageLite); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c0c3ec421979..bb4fd66e995c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -77,6 +77,7 @@ import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ArchivedPackageParcel; import android.content.pm.AuxiliaryResolveInfo; import android.content.pm.ChangedPackages; import android.content.pm.Checksum; @@ -115,7 +116,11 @@ import android.content.pm.UserPackage; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VersionedPackage; import android.content.pm.overlay.OverlayPaths; +import android.content.pm.parsing.ApkLite; +import android.content.pm.parsing.ApkLiteParseUtils; import android.content.pm.parsing.PackageLite; +import android.content.pm.parsing.result.ParseResult; +import android.content.pm.parsing.result.ParseTypeImpl; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; @@ -6298,6 +6303,38 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } + @Override + public ArchivedPackageParcel getArchivedPackage(String apkPath) { + ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); + ParseResult<ApkLite> result = ApkLiteParseUtils.parseApkLite(input.reset(), + new File(apkPath), ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES); + if (result.isError()) { + throw new IllegalArgumentException(result.getErrorMessage(), result.getException()); + } + final ApkLite apk = result.getResult(); + + ArchivedPackageParcel archPkg = new ArchivedPackageParcel(); + archPkg.packageName = apk.getPackageName(); + archPkg.signingDetails = apk.getSigningDetails(); + + archPkg.versionCodeMajor = apk.getVersionCodeMajor(); + archPkg.versionCode = apk.getVersionCode(); + + archPkg.targetSdkVersion = apk.getTargetSdkVersion(); + + // These get translated in flags important for user data management. + archPkg.clearUserDataAllowed = apk.isClearUserDataAllowed(); + archPkg.backupAllowed = apk.isBackupAllowed(); + archPkg.defaultToDeviceProtectedStorage = + apk.isDefaultToDeviceProtectedStorage(); + archPkg.requestLegacyExternalStorage = apk.isRequestLegacyExternalStorage(); + archPkg.userDataFragile = apk.isUserDataFragile(); + archPkg.clearUserDataOnFailedRestoreAllowed = + apk.isClearUserDataOnFailedRestoreAllowed(); + + return archPkg; + } + /** * Wait for the handler to finish handling all pending messages. * @param timeoutMillis Maximum time in milliseconds to wait. @@ -6939,6 +6976,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService return mDistractingPackageHelper.getDistractingPackageRestrictionsAsUser(snapshot, packageNames, userId, callingUid); } + + @Override + public ParceledListSlice<PackageInstaller.SessionInfo> getHistoricalSessions(int userId) { + return mInstallerService.getHistoricalSessions(userId); + } } private void setEnabledOverlayPackages(@UserIdInt int userId, @@ -7754,7 +7796,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService consumer.accept(mPackageStateMutator); mPackageStateMutator.onFinished(); - onChanged(); } return PackageStateMutator.Result.SUCCESS; diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java index db997d8d1d79..2028231ab36b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java @@ -919,16 +919,22 @@ public class PackageManagerServiceUtils { final File packageFile = new File(packagePath); final long sizeBytes; - try { - sizeBytes = InstallLocationUtils.calculateInstalledSize(pkg, abiOverride); - } catch (IOException e) { - if (!packageFile.exists()) { - ret.recommendedInstallLocation = InstallLocationUtils.RECOMMEND_FAILED_INVALID_URI; - } else { - ret.recommendedInstallLocation = InstallLocationUtils.RECOMMEND_FAILED_INVALID_APK; - } + if (!PackageInstallerSession.isArchivedInstallation(flags)) { + try { + sizeBytes = InstallLocationUtils.calculateInstalledSize(pkg, abiOverride); + } catch (IOException e) { + if (!packageFile.exists()) { + ret.recommendedInstallLocation = + InstallLocationUtils.RECOMMEND_FAILED_INVALID_URI; + } else { + ret.recommendedInstallLocation = + InstallLocationUtils.RECOMMEND_FAILED_INVALID_APK; + } - return ret; + return ret; + } + } else { + sizeBytes = 0; } final PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams( diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 2304a2338c46..d9f1df5e02c9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -43,6 +43,7 @@ import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; import android.content.pm.ApplicationInfo; +import android.content.pm.ArchivedPackageParcel; import android.content.pm.FeatureInfo; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageInstaller; @@ -82,6 +83,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.IBinder; import android.os.IUserManager; import android.os.ParcelFileDescriptor; @@ -105,6 +107,7 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.IntArray; +import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; @@ -246,6 +249,8 @@ class PackageManagerShellCommand extends ShellCommand { return runStreamingInstall(); case "install-incremental": return runIncrementalInstall(); + case "install-archived": + return runArchivedInstall(); case "install-abandon": case "install-destroy": return runInstallAbandon(); @@ -1549,6 +1554,16 @@ class PackageManagerShellCommand extends ShellCommand { return doRunInstall(params); } + private int runArchivedInstall() throws RemoteException { + final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); + params.sessionParams.installFlags |= PackageManager.INSTALL_ARCHIVED; + if (params.sessionParams.dataLoaderParams == null) { + params.sessionParams.setDataLoaderParams( + PackageManagerShellCommandDataLoader.getStreamingDataLoaderParams(this)); + } + return doRunInstall(params); + } + private int runIncrementalInstall() throws RemoteException { final InstallParams params = makeInstallParams(UNSUPPORTED_INSTALL_CMD_OPTS); if (params.sessionParams.dataLoaderParams == null) { @@ -1579,6 +1594,8 @@ class PackageManagerShellCommand extends ShellCommand { final boolean isStreaming = params.sessionParams.dataLoaderParams != null; final boolean isApex = (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0; + final boolean installArchived = + (params.sessionParams.installFlags & PackageManager.INSTALL_ARCHIVED) != 0; ArrayList<String> args = getRemainingArgs(); @@ -1595,6 +1612,13 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } + if (installArchived) { + if (hasSplits) { + pw.println("Error: can't have SPLIT(s) for Archival install"); + return 1; + } + } + if (!isStreaming) { if (fromStdIn && hasSplits) { pw.println("Error: can't specify SPLIT(s) along with STDIN"); @@ -1613,8 +1637,8 @@ class PackageManagerShellCommand extends ShellCommand { boolean abandonSession = true; try { if (isStreaming) { - if (doAddFiles(sessionId, args, params.sessionParams.sizeBytes, isApex) - != PackageInstaller.STATUS_SUCCESS) { + if (doAddFiles(sessionId, args, params.sessionParams.sizeBytes, isApex, + installArchived) != PackageInstaller.STATUS_SUCCESS) { return 1; } } else { @@ -3856,7 +3880,7 @@ class PackageManagerShellCommand extends ShellCommand { } private int doAddFiles(int sessionId, ArrayList<String> args, long sessionSizeBytes, - boolean isApex) throws RemoteException { + boolean isApex, boolean installArchived) throws RemoteException { PackageInstaller.Session session = null; try { session = new PackageInstaller.Session( @@ -3865,9 +3889,17 @@ class PackageManagerShellCommand extends ShellCommand { // 1. Single file from stdin. if (args.isEmpty() || STDIN_PATH.equals(args.get(0))) { final String name = "base" + RANDOM.nextInt() + "." + (isApex ? "apex" : "apk"); - final Metadata metadata = Metadata.forStdIn(name); - session.addFile(LOCATION_DATA_APP, name, sessionSizeBytes, - metadata.toByteArray(), null); + final long size; + final Metadata metadata; + if (!installArchived) { + metadata = Metadata.forStdIn(name); + size = sessionSizeBytes; + } else { + metadata = Metadata.forArchived( + getArchivedPackage(STDIN_PATH, sessionSizeBytes)); + size = -1; + } + session.addFile(LOCATION_DATA_APP, name, size, metadata.toByteArray(), null); return 0; } @@ -3876,16 +3908,21 @@ class PackageManagerShellCommand extends ShellCommand { if (delimLocation != -1) { // 2. File with specified size read from stdin. + if (installArchived) { + getOutPrintWriter().println( + "Error: can't install with size from STDIN for Archival install"); + return 1; + } if (processArgForStdin(arg, session) != 0) { return 1; } } else { // 3. Local file. - processArgForLocalFile(arg, session); + processArgForLocalFile(arg, session, installArchived); } } return 0; - } catch (IllegalArgumentException e) { + } catch (IOException | IllegalArgumentException e) { getErrPrintWriter().println("Failed to add file(s), reason: " + e); getOutPrintWriter().println("Failure [failed to add file(s)]"); return 1; @@ -3974,26 +4011,67 @@ class PackageManagerShellCommand extends ShellCommand { } } - private void processArgForLocalFile(String arg, PackageInstaller.Session session) { + private ArchivedPackageParcel getArchivedPackage(String inPath, long sizeBytes) + throws RemoteException, IOException { + final var fdWithSize = openInFile(inPath, sizeBytes); + if (fdWithSize.first == null) { + throw new IllegalArgumentException("Error: Can't open file: " + inPath); + } + + File tmpFile = null; + final ParcelFileDescriptor fd = fdWithSize.first; + try (InputStream inStream = new AutoCloseInputStream(fd)) { + final long identity = Binder.clearCallingIdentity(); + try { + File tmpStagingDir = Environment.getDataAppDirectory(null); + tmpFile = new File(tmpStagingDir, "tmdl" + RANDOM.nextInt() + ".tmp"); + + try (OutputStream outStream = new FileOutputStream(tmpFile)) { + Streams.copy(inStream, outStream); + } + + return mInterface.getArchivedPackage(tmpFile.getAbsolutePath()); + } finally { + if (tmpFile != null) { + tmpFile.delete(); + } + Binder.restoreCallingIdentity(identity); + } + } catch (IOException e) { + throw new IllegalArgumentException("Error: Can't stage file: " + inPath, e); + } + } + + private void processArgForLocalFile(String arg, PackageInstaller.Session session, + boolean installArchived) throws IOException, RemoteException { final String inPath = arg; final File file = new File(inPath); final String name = file.getName(); - final long size = getFileStatSize(file); - final Metadata metadata = Metadata.forLocalFile(inPath); + final long size; + final Metadata metadata; + if (installArchived) { + metadata = Metadata.forArchived(getArchivedPackage(inPath, -1)); + size = 0; + } else { + metadata = Metadata.forLocalFile(inPath); + size = getFileStatSize(file); + } byte[] v4signatureBytes = null; - // Try to load the v4 signature file for the APK; it might not exist. - final String v4SignaturePath = inPath + V4Signature.EXT; - final ParcelFileDescriptor pfd = openFileForSystem(v4SignaturePath, "r"); - if (pfd != null) { - try { - final V4Signature v4signature = V4Signature.readFrom(pfd); - v4signatureBytes = v4signature.toByteArray(); - } catch (IOException ex) { - Slog.e(TAG, "V4 signature file exists but failed to be parsed.", ex); - } finally { - IoUtils.closeQuietly(pfd); + if (!installArchived) { + // Try to load the v4 signature file for the APK; it might not exist. + final String v4SignaturePath = inPath + V4Signature.EXT; + final ParcelFileDescriptor pfd = openFileForSystem(v4SignaturePath, "r"); + if (pfd != null) { + try { + final V4Signature v4signature = V4Signature.readFrom(pfd); + v4signatureBytes = v4signature.toByteArray(); + } catch (IOException ex) { + Slog.e(TAG, "V4 signature file exists but failed to be parsed.", ex); + } finally { + IoUtils.closeQuietly(pfd); + } } } @@ -4015,6 +4093,32 @@ class PackageManagerShellCommand extends ShellCommand { return 0; } + private Pair<ParcelFileDescriptor, Long> openInFile(String inPath, long sizeBytes) + throws IOException { + final ParcelFileDescriptor fd; + if (STDIN_PATH.equals(inPath)) { + fd = ParcelFileDescriptor.dup(getInFileDescriptor()); + } else if (inPath != null) { + fd = openFileForSystem(inPath, "r"); + if (fd == null) { + return Pair.create(null, -1L); + } + sizeBytes = fd.getStatSize(); + if (sizeBytes < 0) { + fd.close(); + getErrPrintWriter().println("Unable to get size of: " + inPath); + return Pair.create(null, -1L); + } + } else { + fd = ParcelFileDescriptor.dup(getInFileDescriptor()); + } + if (sizeBytes <= 0) { + getErrPrintWriter().println("Error: must specify an APK size"); + return Pair.create(null, 1L); + } + return Pair.create(fd, sizeBytes); + } + private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess) throws RemoteException { PackageInstaller.Session session = null; @@ -4024,26 +4128,13 @@ class PackageManagerShellCommand extends ShellCommand { final PrintWriter pw = getOutPrintWriter(); - final ParcelFileDescriptor fd; - if (STDIN_PATH.equals(inPath)) { - fd = ParcelFileDescriptor.dup(getInFileDescriptor()); - } else if (inPath != null) { - fd = openFileForSystem(inPath, "r"); - if (fd == null) { - return -1; - } - sizeBytes = fd.getStatSize(); - if (sizeBytes < 0) { - getErrPrintWriter().println("Unable to get size of: " + inPath); - return -1; - } - } else { - fd = ParcelFileDescriptor.dup(getInFileDescriptor()); - } - if (sizeBytes <= 0) { - getErrPrintWriter().println("Error: must specify an APK size"); - return 1; + final var fdWithSize = openInFile(inPath, sizeBytes); + if (fdWithSize.first == null) { + long resultCode = fdWithSize.second; + return (int) resultCode; } + final ParcelFileDescriptor fd = fdWithSize.first; + sizeBytes = fdWithSize.second; session.write(splitName, 0, sizeBytes, fd); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java index a1e5153194c1..fbe5a51587fc 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java @@ -18,9 +18,11 @@ package com.android.server.pm; import android.annotation.NonNull; import android.content.ComponentName; +import android.content.pm.ArchivedPackageParcel; import android.content.pm.DataLoaderParams; import android.content.pm.InstallationFile; import android.content.pm.PackageInstaller; +import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.ShellCommand; import android.service.dataloader.DataLoaderService; @@ -37,6 +39,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; +import java.util.Arrays; import java.util.Collection; import java.util.concurrent.atomic.AtomicLong; @@ -136,9 +139,13 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { * Everything streamed. */ static final byte STREAMING = 3; + /** + * Archived install. + */ + static final byte ARCHIVED = 4; private final byte mMode; - private final String mData; + private final byte[] mData; private final String mSalt; private static AtomicLong sGlobalSalt = new AtomicLong((new SecureRandom()).nextLong()); @@ -156,6 +163,21 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { return new Metadata(LOCAL_FILE, filePath, nextGlobalSalt().toString()); } + /** @hide */ + @VisibleForTesting + public static Metadata forArchived(ArchivedPackageParcel archivedPackage) { + Parcel parcel = Parcel.obtain(); + byte[] bytes; + try { + parcel.writeParcelable(archivedPackage, 0); + bytes = parcel.marshall(); + } finally { + parcel.recycle(); + } + + return new Metadata(ARCHIVED, bytes, null); + } + static Metadata forDataOnlyStreaming(String fileId) { return new Metadata(DATA_ONLY_STREAMING, fileId); } @@ -169,8 +191,12 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { } private Metadata(byte mode, String data, String salt) { + this(mode, (data != null ? data : "").getBytes(StandardCharsets.UTF_8), salt); + } + + private Metadata(byte mode, byte[] data, String salt) { this.mMode = mode; - this.mData = (data == null) ? "" : data; + this.mData = data; this.mSalt = salt; } @@ -181,22 +207,21 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { int offset = 0; final byte mode = bytes[offset]; offset += 1; - final String data; + final byte[] data; final String salt; switch (mode) { case LOCAL_FILE: { int dataSize = ByteBuffer.wrap(bytes, offset, 4).order( ByteOrder.LITTLE_ENDIAN).getInt(); offset += 4; - data = new String(bytes, offset, dataSize, StandardCharsets.UTF_8); + data = Arrays.copyOfRange(bytes, offset, offset + dataSize); offset += dataSize; salt = new String(bytes, offset, bytes.length - offset, StandardCharsets.UTF_8); break; } default: - data = new String(bytes, offset, bytes.length - offset, - StandardCharsets.UTF_8); + data = Arrays.copyOfRange(bytes, offset, bytes.length); salt = null; break; } @@ -207,7 +232,7 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { @VisibleForTesting public byte[] toByteArray() { final byte[] result; - final byte[] dataBytes = this.mData.getBytes(StandardCharsets.UTF_8); + final byte[] dataBytes = this.mData; switch (this.mMode) { case LOCAL_FILE: { int dataSize = dataBytes.length; @@ -237,9 +262,26 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { return this.mMode; } - String getData() { + byte[] getData() { return this.mData; } + + ArchivedPackageParcel getArchivedPackage() { + if (getMode() != ARCHIVED) { + throw new IllegalStateException("Not an archived package metadata."); + } + + Parcel parcel = Parcel.obtain(); + ArchivedPackageParcel result; + try { + parcel.unmarshall(this.mData, 0, this.mData.length); + parcel.setDataPosition(0); + result = parcel.readParcelable(ArchivedPackageParcel.class.getClassLoader()); + } finally { + parcel.recycle(); + } + return result; + } } private static class DataLoader implements DataLoaderService.DataLoader { @@ -278,7 +320,9 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { case Metadata.LOCAL_FILE: { ParcelFileDescriptor incomingFd = null; try { - incomingFd = getLocalFilePFD(shellCommand, metadata.getData()); + final String filePath = new String(metadata.getData(), + StandardCharsets.UTF_8); + incomingFd = getLocalFilePFD(shellCommand, filePath); mConnector.writeData(file.getName(), 0, incomingFd.getStatSize(), incomingFd); } finally { @@ -286,6 +330,10 @@ public class PackageManagerShellCommandDataLoader extends DataLoaderService { } break; } + case Metadata.ARCHIVED: { + // Do nothing, metadata already contains everything needed for install. + break; + } default: Slog.e(TAG, "Unsupported metadata mode: " + metadata.getMode()); return false; diff --git a/services/core/java/com/android/server/pm/PrepareFailure.java b/services/core/java/com/android/server/pm/PrepareFailure.java index 3180bac2e7b3..09cb6b907e23 100644 --- a/services/core/java/com/android/server/pm/PrepareFailure.java +++ b/services/core/java/com/android/server/pm/PrepareFailure.java @@ -42,7 +42,8 @@ final class PrepareFailure extends PackageManagerException { } PrepareFailure(String message, Exception e) { - super(((PackageManagerException) e).error, + super(e instanceof PackageManagerException ? ((PackageManagerException) e).error + : PackageManager.INSTALL_FAILED_INTERNAL_ERROR, ExceptionUtils.getCompleteMessage(message, e)); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index d2adfddb4be3..6eace6a920aa 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2065,8 +2065,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile ATTR_ARCHIVE_ACTIVITY_TITLE); Path iconPath = Path.of(parser.getAttributeValue(null, ATTR_ARCHIVE_ICON_PATH)); - Path monochromeIconPath = Path.of(parser.getAttributeValue(null, - ATTR_ARCHIVE_MONOCHROME_ICON_PATH)); + String monochromeAttribute = parser.getAttributeValue(null, + ATTR_ARCHIVE_MONOCHROME_ICON_PATH); + Path monochromeIconPath = monochromeAttribute == null ? null : Path.of( + monochromeAttribute); if (title == null || iconPath == null) { Slog.wtf(TAG, @@ -2916,11 +2918,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile StringBuilder sb = new StringBuilder(); for (final PackageSetting ps : mPackages.values()) { - // TODO(b/135203078): This doesn't handle multiple users - final String dataPath = PackageInfoUtils.getDataDir(ps, UserHandle.USER_SYSTEM) - .getAbsolutePath(); - - if (ps.getPkg() == null || dataPath == null) { + if (ps.getPkg() == null) { if (!"android".equals(ps.getPackageName())) { Slog.w(TAG, "Skipping " + ps + " due to missing metadata"); } @@ -2932,6 +2930,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile continue; } + // TODO(b/135203078): This doesn't handle multiple users + final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.USER_SYSTEM); + final String dataPath = dataDir == null ? "null" : dataDir.getAbsolutePath(); + final boolean isDebug = ps.getPkg().isDebuggable(); final IntArray gids = new IntArray(); for (final int userId : userIds) { @@ -2973,7 +2975,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile sb.append(ps.getSeInfo()); sb.append(" "); final int gidsSize = gids.size(); - if (gids != null && gids.size() > 0) { + if (gids.size() > 0) { sb.append(gids.get(0)); for (int i = 1; i < gidsSize; i++) { sb.append(","); @@ -4746,6 +4748,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD", ApplicationInfo.PRIVATE_FLAG_ODM, "ODM", ApplicationInfo.PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING, "PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING", + ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA, "PRIVATE_FLAG_HAS_FRAGILE_USER_DATA", }; void dumpVersionLPr(IndentingPrintWriter pw) { @@ -4893,6 +4896,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile pw.print("]"); } pw.println(); + File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId()); + pw.print(prefix); pw.print(" dataDir="); pw.println(dataDir.getAbsolutePath()); if (pkg != null) { pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName()); pw.print(prefix); pw.print(" usesNonSdkApi="); pw.println(pkg.isNonSdkApiRequested()); @@ -5193,10 +5198,6 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile pw.print(" installReason="); pw.println(userState.getInstallReason()); - final File dataDir = PackageInfoUtils.getDataDir(ps, user.id); - pw.print(" dataDir="); - pw.println(dataDir == null ? "null" : dataDir.getAbsolutePath()); - final PackageUserStateInternal pus = ps.readUserState(user.id); pw.print(" firstInstallTime="); date.setTime(pus.getFirstInstallTimeMillis()); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 3e4dd1637387..c6aba2ab9cbe 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -1743,6 +1743,10 @@ public class ShortcutService extends IShortcutService.Stub { android.util.EventLog.writeEvent(0x534e4554, "109824443", -1, ""); throw new SecurityException("Shortcut package name mismatch"); } + final int callingUid = injectBinderCallingUid(); + if (UserHandle.getUserId(callingUid) != si.getUserId()) { + throw new SecurityException("User-ID in shortcut doesn't match the caller"); + } } private void verifyShortcutInfoPackages( diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index f2797eb48305..803b94be3c7a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -23,6 +23,7 @@ import static android.os.UserManager.DISALLOW_USER_SWITCH; import static android.os.UserManager.SYSTEM_USER_MODE_EMULATION_PROPERTY; import static android.os.UserManager.USER_OPERATION_ERROR_UNKNOWN; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_ABORTED; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_UNSPECIFIED; import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_USER_ALREADY_AN_ADMIN; @@ -2938,8 +2939,10 @@ public class UserManagerService extends IUserManager.Stub { UserHandle.USER_NULL, UserManager.RESTRICTION_SOURCE_SYSTEM)); } - result.addAll(getDevicePolicyManagerInternal() - .getUserRestrictionSources(restrictionKey, userId)); + final DevicePolicyManagerInternal dpmi = getDevicePolicyManagerInternal(); + if (dpmi != null) { + result.addAll(dpmi.getUserRestrictionSources(restrictionKey, userId)); + } return result; } @@ -4787,11 +4790,14 @@ public class UserManagerService extends IUserManager.Stub { // default check is for DISALLOW_ADD_USER // If new user is of type CLONE, check if creation of clone profile is allowed // If new user is of type MANAGED, check if creation of managed profile is allowed + // If new user is of type PRIVATE, check if creation of private profile is allowed String restriction = UserManager.DISALLOW_ADD_USER; if (UserManager.isUserTypeCloneProfile(userType)) { restriction = UserManager.DISALLOW_ADD_CLONE_PROFILE; } else if (UserManager.isUserTypeManagedProfile(userType)) { restriction = UserManager.DISALLOW_ADD_MANAGED_PROFILE; + } else if (UserManager.isUserTypePrivateProfile(userType)) { + restriction = UserManager.DISALLOW_ADD_PRIVATE_PROFILE; } enforceUserRestriction(restriction, UserHandle.getCallingUserId(), @@ -5329,12 +5335,12 @@ public class UserManagerService extends IUserManager.Stub { statsManager.setPullAtomCallback( FrameworkStatsLog.USER_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); statsManager.setPullAtomCallback( FrameworkStatsLog.MULTI_USER_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index 4e2ceab290d4..35861d79875d 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -103,6 +103,7 @@ public class UserRestrictionsUtils { UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_ADD_MANAGED_PROFILE, UserManager.DISALLOW_ADD_CLONE_PROFILE, + UserManager.DISALLOW_ADD_PRIVATE_PROFILE, UserManager.ENSURE_VERIFY_APPS, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, @@ -212,7 +213,8 @@ public class UserRestrictionsUtils { private static final Set<String> IMMUTABLE_BY_OWNERS = Sets.newArraySet( UserManager.DISALLOW_RECORD_AUDIO, UserManager.DISALLOW_WALLPAPER, - UserManager.DISALLOW_OEM_UNLOCK + UserManager.DISALLOW_OEM_UNLOCK, + UserManager.DISALLOW_ADD_PRIVATE_PROFILE ); /** diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java index b7f9aafc53f8..85b60a07b003 100644 --- a/services/core/java/com/android/server/pm/UserTypeFactory.java +++ b/services/core/java/com/android/server/pm/UserTypeFactory.java @@ -51,6 +51,7 @@ import android.os.UserManager; import android.util.ArrayMap; import android.util.Slog; +import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; @@ -284,9 +285,9 @@ public final class UserTypeFactory { .setBadgeLabels( com.android.internal.R.string.private_profile_label_badge) .setBadgeColors( - com.android.internal.R.color.system_accent1_900) + R.color.black) .setDarkThemeBadgeColors( - com.android.internal.R.color.system_accent1_900) + R.color.white) .setDefaultRestrictions(getDefaultProfileRestrictions()) .setDefaultSecureSettings(getDefaultNonManagedProfileSecureSettings()) .setDefaultUserProperties(new UserProperties.Builder() diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java index 3a1fd7cfb451..8c73ce8b6b95 100644 --- a/services/core/java/com/android/server/pm/VerifyingSession.java +++ b/services/core/java/com/android/server/pm/VerifyingSession.java @@ -191,7 +191,7 @@ final class VerifyingSession { // Perform package verification and enable rollback (unless we are simply moving the // package). if (!mOriginInfo.mExisting) { - if (!isApex()) { + if (!isApex() && !isArchivedInstallation()) { // TODO(b/182426975): treat APEX as APK when APK verification is concerned sendApkVerificationRequest(pkgLite); } @@ -896,6 +896,9 @@ final class VerifyingSession { public boolean isApex() { return (mInstallFlags & PackageManager.INSTALL_APEX) != 0; } + public boolean isArchivedInstallation() { + return (mInstallFlags & PackageManager.INSTALL_ARCHIVED) != 0; + } public boolean isStaged() { return mIsStaged; } diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index f4f03f4c9c4e..31856f1630bb 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -544,6 +544,11 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { */ public boolean compileLayouts(@NonNull PackageStateInternal ps, @NonNull AndroidPackage pkg) { try { + final String packageName = pkg.getPackageName(); + final String apkPath = pkg.getSplits().get(0).getPath(); + // TODO(b/143971007): Use a cross-user directory + File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId()); + final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex"; if (ps.isPrivileged() || pkg.isUseEmbeddedDex() || pkg.isDefaultToDeviceProtectedStorage()) { // Privileged apps prefer to load trusted code so they don't use compiled views. @@ -553,14 +558,6 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { // selinux permissions required for writing to user_de. return false; } - final String packageName = pkg.getPackageName(); - final String apkPath = pkg.getSplits().get(0).getPath(); - final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId()); - if (dataDir == null) { - // The app is not installed on the target user and doesn't have a data dir - return false; - } - final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex"; Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath + ") to " + outDexFile); final long callingId = Binder.clearCallingIdentity(); diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java index c5b65a3641c1..6405ea5667d3 100644 --- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java +++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java @@ -40,11 +40,8 @@ public class ViewCompiler { public boolean compileLayouts(PackageStateInternal ps, String apkPath) { try { final String packageName = ps.getPackageName(); - final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId()); - if (dataDir == null) { - // The app is not installed on the target user and doesn't have a data dir - return false; - } + // TODO(b/143971007): Use a cross-user directory + File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId()); final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex"; Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath + ") to " + outDexFile); diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index fc079093c9e3..4eceb7738836 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -443,7 +443,7 @@ public class PackageInfoUtils { updateApplicationInfo(info, flags, state); - initForUser(info, pkg, userId, state); + initForUser(info, pkg, userId); // TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up PackageStateUnserialized pkgState = pkgSetting.getTransientState(); @@ -689,7 +689,7 @@ public class PackageInfoUtils { info.splitDependencies = pkg.getSplitDependencies().size() == 0 ? null : pkg.getSplitDependencies(); - initForUser(info, pkg, userId, state); + initForUser(info, pkg, userId); info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi(); info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi(); @@ -802,9 +802,7 @@ public class PackageInfoUtils { // If available for the target user, or trying to match uninstalled packages and it's // a system app. return PackageUserStateUtils.isAvailable(state, flags) - || (pkgSetting.isSystem() - && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 - || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); + || (pkgSetting.isSystem() && matchUninstalledOrHidden(flags)); } private static boolean checkUseInstalledOrHidden(long flags, @@ -819,9 +817,15 @@ public class PackageInfoUtils { // If available for the target user, or trying to match uninstalled packages and it's // a system app. return PackageUserStateUtils.isAvailable(state, flags) - || (appInfo != null && appInfo.isSystemApp() - && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0 - || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0)); + || (appInfo != null && appInfo.isSystemApp() && matchUninstalledOrHidden(flags)); + } + + private static boolean matchUninstalledOrHidden(long flags) { + return (flags + & (PackageManager.MATCH_KNOWN_PACKAGES + | PackageManager.MATCH_ARCHIVED_PACKAGES + | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS)) + != 0; } private static void assignFieldsComponentInfoParsedMainComponent( @@ -1001,7 +1005,7 @@ public class PackageInfoUtils { } private static void initForUser(ApplicationInfo output, AndroidPackage input, - @UserIdInt int userId, PackageUserStateInternal state) { + @UserIdInt int userId) { PackageImpl pkg = ((PackageImpl) input); String packageName = input.getPackageName(); output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid())); @@ -1011,12 +1015,6 @@ public class PackageInfoUtils { return; } - if (!pkg.isSystem() && state.getCeDataInode() <= 0) { - // The data dir has been deleted - output.dataDir = null; - return; - } - // For performance reasons, all these paths are built as strings if (userId == UserHandle.USER_SYSTEM) { output.credentialProtectedDataDir = @@ -1051,7 +1049,7 @@ public class PackageInfoUtils { // This duplicates the ApplicationInfo variant because it uses field assignment and the classes // don't inherit from each other, unfortunately. Consolidating logic would introduce overhead. private static void initForUser(InstrumentationInfo output, AndroidPackage input, - @UserIdInt int userId, PackageUserStateInternal state) { + @UserIdInt int userId) { PackageImpl pkg = ((PackageImpl) input); String packageName = input.getPackageName(); if ("android".equals(packageName)) { @@ -1059,12 +1057,6 @@ public class PackageInfoUtils { return; } - if (!pkg.isSystem() && state.getCeDataInode() <= 0) { - // The data dir has been deleted - output.dataDir = null; - return; - } - // For performance reasons, all these paths are built as strings if (userId == UserHandle.USER_SYSTEM) { output.credentialProtectedDataDir = @@ -1096,21 +1088,12 @@ public class PackageInfoUtils { } } - /** - * Returns the data dir of the app for the target user. Return null if the app isn't installed - * on the target user and doesn't have a data dir on the target user. - */ - @Nullable + @NonNull public static File getDataDir(PackageStateInternal ps, int userId) { if ("android".equals(ps.getPackageName())) { return Environment.getDataSystemDirectory(); } - if (!ps.isSystem() && ps.getUserStateOrDefault(userId).getCeDataInode() <= 0) { - // The data dir has been deleted - return null; - } - if (ps.isDefaultToDeviceProtectedStorage() && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId, diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java index f5ba3f61a00c..d82a5000844f 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java +++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.app.ActivityThread; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.parsing.PackageLite; import android.content.pm.parsing.result.ParseInput; import android.content.pm.parsing.result.ParseResult; import android.content.pm.parsing.result.ParseTypeImpl; @@ -183,6 +184,23 @@ public class PackageParser2 implements AutoCloseable { } /** + * Creates a ParsedPackage from PackageLite without any additional parsing or processing. + * Most fields will get reasonable default values, corresponding to "deleted-keep-data". + */ + @AnyThread + public ParsedPackage parsePackageFromPackageLite(PackageLite packageLite, int flags) + throws PackageManagerException { + ParseInput input = mSharedResult.get().reset(); + ParseResult<ParsingPackage> result = parsingUtils.parsePackageFromPackageLite(input, + packageLite, flags); + if (result.isError()) { + throw new PackageManagerException(result.getErrorCode(), result.getErrorMessage(), + result.getException()); + } + return result.getResult().hideAsParsed(); + } + + /** * Removes the cached value for the thread the parser was created on. It is assumed that * any threads created for parallel parsing will be created and released, so they don't * need an explicit close call. diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index b01a89e672be..fc6b12c78208 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1024,7 +1024,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { } synchronized (mLock) { - mAttributions.put(source.getToken(), source); + // Change the token for the AttributionSource we're storing, so that we don't store + // a strong reference to the original token inside the map itself. + mAttributions.put(source.getToken(), source.withDefaultToken()); } } @@ -1032,7 +1034,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { final AttributionSource cachedSource = mAttributions.get(source.getToken()); if (cachedSource != null) { - return cachedSource.equals(source); + return cachedSource.equalsExceptToken(source); } return false; } diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateUtils.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateUtils.java index e3424534c275..54f7ebca1b66 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageUserStateUtils.java +++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateUtils.java @@ -87,9 +87,10 @@ public class PackageUserStateUtils { // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0; final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0; + final boolean matchArchived = (flags & PackageManager.MATCH_ARCHIVED_PACKAGES) != 0; return matchAnyUser || (state.isInstalled() - && (!state.isHidden() || matchUninstalled)); + && (!state.isHidden() || matchUninstalled || matchArchived)); } public static boolean reportIfDebug(boolean result, long flags) { diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java index f1f0fa35578d..699ccbdc5a83 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java @@ -375,6 +375,10 @@ public interface ParsingPackage { ParsingPackage setBaseRevisionCode(int baseRevisionCode); + ParsingPackage setVersionCode(int vesionCode); + + ParsingPackage setVersionCodeMajor(int vesionCodeMajor); + ParsingPackage setVersionName(String versionName); ParsingPackage setCompileSdkVersion(int compileSdkVersion); diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index dc022f70e47c..2d55b9f8e16a 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -474,15 +474,121 @@ public class ParsingPackageUtils { } } - private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, File apkFile, - String codePath, SplitAssetLoader assetLoader, int flags) { - final String apkPath = apkFile.getAbsolutePath(); + /** + * Creates ParsingPackage using only PackageLite. + * Missing fields will contain reasonable defaults. + * Used for packageless (aka archived) package installation. + */ + public ParseResult<ParsingPackage> parsePackageFromPackageLite(ParseInput input, + PackageLite lite, int flags) { + final String volumeUuid = getVolumeUuid(lite.getPath()); + final String pkgName = lite.getPackageName(); + + final TypedArray manifestArray = null; + final ParsingPackage pkg = mCallback.startParsingPackage(pkgName, + lite.getBaseApkPath(), lite.getPath(), manifestArray, lite.isCoreApp()); + + final int targetSdk = lite.getTargetSdk(); + final String versionName = null; + final int compileSdkVersion = 0; + final String compileSdkVersionCodeName = null; + final boolean isolatedSplitLoading = false; + + // Normally set from manifestArray. + pkg.setVersionCode(lite.getVersionCode()); + pkg.setVersionCodeMajor(lite.getVersionCodeMajor()); + pkg.setBaseRevisionCode(lite.getBaseRevisionCode()); + pkg.setVersionName(versionName); + pkg.setCompileSdkVersion(compileSdkVersion); + pkg.setCompileSdkVersionCodeName(compileSdkVersionCodeName); + pkg.setIsolatedSplitLoading(isolatedSplitLoading); + pkg.setTargetSdkVersion(targetSdk); + + // parseBaseApkTags + pkg.setInstallLocation(lite.getInstallLocation()) + .setTargetSandboxVersion(PARSE_DEFAULT_TARGET_SANDBOX) + /* Set the global "on SD card" flag */ + .setExternalStorage((flags & PARSE_EXTERNAL_STORAGE) != 0); + + // parseBaseAppBasicFlags + pkg + // Default true + .setBackupAllowed(lite.isBackupAllowed()) + .setClearUserDataAllowed(lite.isClearUserDataAllowed()) + .setClearUserDataOnFailedRestoreAllowed( + lite.isClearUserDataOnFailedRestoreAllowed()) + .setAllowNativeHeapPointerTagging(true) + .setEnabled(true) + .setExtractNativeLibrariesRequested(true) + // targetSdkVersion gated + .setAllowAudioPlaybackCapture(targetSdk >= Build.VERSION_CODES.Q) + .setHardwareAccelerated(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) + .setRequestLegacyExternalStorage(lite.isRequestLegacyExternalStorage()) + .setCleartextTrafficAllowed(targetSdk < Build.VERSION_CODES.P) + // Default false + .setDefaultToDeviceProtectedStorage(lite.isDefaultToDeviceProtectedStorage()) + .setUserDataFragile(lite.isUserDataFragile()) + // Ints + .setCategory(ApplicationInfo.CATEGORY_UNDEFINED) + // Floats Default 0f + .setMaxAspectRatio(0f) + .setMinAspectRatio(0f); + + // No APK - no code. + pkg.setDeclaredHavingCode(false); + + final String taskAffinity = null; + ParseResult<String> taskAffinityResult = ComponentParseUtils.buildTaskAffinityName( + pkgName, pkgName, taskAffinity, input); + if (taskAffinityResult.isError()) { + return input.error(taskAffinityResult); + } + pkg.setTaskAffinity(taskAffinityResult.getResult()); + + final CharSequence pname = null; + ParseResult<String> processNameResult = ComponentParseUtils.buildProcessName( + pkgName, null /*defProc*/, pname, flags, mSeparateProcesses, input); + if (processNameResult.isError()) { + return input.error(processNameResult); + } + pkg.setProcessName(processNameResult.getResult()); + + pkg.setGwpAsanMode(-1); + pkg.setMemtagMode(-1); + + afterParseBaseApplication(pkg); + + final ParseResult<ParsingPackage> result = validateBaseApkTags(input, pkg); + if (result.isError()) { + return result; + } + + pkg.setVolumeUuid(volumeUuid); + + if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) { + pkg.setSigningDetails(lite.getSigningDetails()); + } else { + pkg.setSigningDetails(SigningDetails.UNKNOWN); + } + return input.success(pkg + .set32BitAbiPreferred(lite.isUse32bitAbi())); + } + + private static String getVolumeUuid(final String apkPath) { String volumeUuid = null; if (apkPath.startsWith(MNT_EXPAND)) { final int end = apkPath.indexOf('/', MNT_EXPAND.length()); volumeUuid = apkPath.substring(MNT_EXPAND.length(), end); } + return volumeUuid; + } + + private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, File apkFile, + String codePath, SplitAssetLoader assetLoader, int flags) { + final String apkPath = apkFile.getAbsolutePath(); + + final String volumeUuid = getVolumeUuid(apkPath); if (DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath); @@ -882,7 +988,7 @@ public class ParsingPackageUtils { } pkg.setInstallLocation(anInteger(PARSE_DEFAULT_INSTALL_LOCATION, - R.styleable.AndroidManifest_installLocation, sa)) + R.styleable.AndroidManifest_installLocation, sa)) .setTargetSandboxVersion(anInteger(PARSE_DEFAULT_TARGET_SANDBOX, R.styleable.AndroidManifest_targetSandboxVersion, sa)) /* Set the global "on SD card" flag */ @@ -932,6 +1038,10 @@ public class ParsingPackageUtils { } } + return validateBaseApkTags(input, pkg); + } + + private ParseResult<ParsingPackage> validateBaseApkTags(ParseInput input, ParsingPackage pkg) { if (!ParsedAttributionUtils.isCombinationValid(pkg.getAttributions())) { return input.error( INSTALL_PARSE_FAILED_BAD_MANIFEST, @@ -2199,15 +2309,19 @@ public class ParsingPackageUtils { pkg.sortServices(); } - // Must be run after the entire {@link ApplicationInfo} has been fully processed and after - // every activity info has had a chance to set it from its attributes. + afterParseBaseApplication(pkg); + + return input.success(pkg); + } + + // Must be run after the entire {@link ApplicationInfo} has been fully processed and after + // every activity info has had a chance to set it from its attributes. + private void afterParseBaseApplication(ParsingPackage pkg) { setMaxAspectRatio(pkg); setMinAspectRatio(pkg); setSupportsSizeChanges(pkg); pkg.setHasDomainUrls(hasDomainURLs(pkg)); - - return input.success(pkg); } /** diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b3aa09b8f17b..63794d57fabc 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -559,6 +559,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mWakeOnDpadKeyPress; boolean mWakeOnAssistKeyPress; boolean mWakeOnBackKeyPress; + boolean mSilenceRingerOnSleepKey; long mWakeUpToLastStateTimeout; int mSearchKeyBehavior; ComponentName mSearchKeyTargetActivity; @@ -1423,6 +1424,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private void sleepRelease(long eventTime) { + if (mSilenceRingerOnSleepKey) { + TelecomManager telecomManager = getTelecommService(); + if (telecomManager != null && telecomManager.isRinging()) { + telecomManager.silenceRinger(); + Slog.i(TAG, "sleepRelease() silence ringer"); + return; + } + } + switch (mShortPressOnSleepBehavior) { case SHORT_PRESS_SLEEP_GO_TO_SLEEP: case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: @@ -2347,6 +2357,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.string.config_primaryShortPressTargetActivity)); mShortPressOnSleepBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_shortPressOnSleepBehavior); + mSilenceRingerOnSleepKey = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_silenceRingerOnSleepKey); mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean( com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup); @@ -3342,6 +3354,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { return true; } break; + case KeyEvent.KEYCODE_DEL: + case KeyEvent.KEYCODE_GRAVE: + if (firstDown && event.isMetaPressed()) { + logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK); + injectBackGesture(event.getDownTime()); + return true; + } case KeyEvent.KEYCODE_DPAD_UP: if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) { StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); @@ -3353,9 +3372,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } break; case KeyEvent.KEYCODE_DPAD_LEFT: - if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) { - enterStageSplitFromRunningApp(true /* leftOrTop */); - logKeyboardSystemsEvent(event, KeyboardLogEvent.SPLIT_SCREEN_NAVIGATION); + if (firstDown && event.isMetaPressed()) { + if (event.isCtrlPressed()) { + enterStageSplitFromRunningApp(true /* leftOrTop */); + logKeyboardSystemsEvent(event, KeyboardLogEvent.SPLIT_SCREEN_NAVIGATION); + } else { + logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK); + injectBackGesture(event.getDownTime()); + } return true; } break; @@ -3618,6 +3642,25 @@ public class PhoneWindowManager implements WindowManagerPolicy { return (metaState & KeyEvent.META_META_ON) != 0; } + @SuppressLint("MissingPermission") + private void injectBackGesture(long downtime) { + // Create and inject down event + KeyEvent downEvent = new KeyEvent(downtime, downtime, KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */, + KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, + InputDevice.SOURCE_KEYBOARD); + mInputManager.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + + + // Create and inject up event + KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP); + mInputManager.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + + downEvent.recycle(); + upEvent.recycle(); + } + private boolean handleHomeShortcuts(int displayId, IBinder focusedToken, KeyEvent event) { // First we always handle the home key here, so applications // can never break it, although if keyguard is on, we do let diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java index 33bed3d42e50..88c2e095453d 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -16,6 +16,8 @@ package com.android.server.power.hint; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityManagerInternal; @@ -37,7 +39,6 @@ import android.util.StatsEvent; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.Preconditions; @@ -142,7 +143,7 @@ public final class HintManagerService extends SystemService { statsManager.setPullAtomCallback( FrameworkStatsLog.ADPF_SYSTEM_COMPONENT_INFO, null, // use default PullAtomMetadata values - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, this::onPullAtom); } diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java index 3a3273328a7a..f6fa9f244252 100644 --- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java +++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java @@ -170,10 +170,11 @@ public class BatteryUsageStatsProvider { && mStats.isProcessStateDataAvailable(); final boolean includeVirtualUids = ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_VIRTUAL_UIDS) != 0); + final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold(); final BatteryUsageStats.Builder batteryUsageStatsBuilder = new BatteryUsageStats.Builder( mStats.getCustomEnergyConsumerNames(), includePowerModels, - includeProcessStateData); + includeProcessStateData, minConsumedPowerThreshold); // TODO(b/188068523): use a monotonic clock to ensure resilience of order and duration // of stats sessions to wall-clock adjustments batteryUsageStatsBuilder.setStatsStartTimestamp(mStats.getStartClockTime()); @@ -307,10 +308,12 @@ public class BatteryUsageStatsProvider { final boolean includeProcessStateData = ((query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0) && mStats.isProcessStateDataAvailable(); + final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold(); final String[] customEnergyConsumerNames = mStats.getCustomEnergyConsumerNames(); final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder( - customEnergyConsumerNames, includePowerModels, includeProcessStateData); + customEnergyConsumerNames, includePowerModels, includeProcessStateData, + minConsumedPowerThreshold); if (mBatteryUsageStatsStore == null) { Log.e(TAG, "BatteryUsageStatsStore is unavailable"); return builder.build(); diff --git a/services/core/java/com/android/server/security/Android.bp b/services/core/java/com/android/server/security/Android.bp new file mode 100644 index 000000000000..3f644c44111a --- /dev/null +++ b/services/core/java/com/android/server/security/Android.bp @@ -0,0 +1,17 @@ +aconfig_declarations { + name: "com.android.server.security.flags-aconfig", + package: "com.android.server.security", + srcs: ["*.aconfig"], +} + +java_aconfig_library { + name: "com.android.server.security.flags-aconfig-java", + aconfig_declarations: "com.android.server.security.flags-aconfig", +} + +java_aconfig_library { + name: "com.android.server.security.flags-aconfig-java-host", + aconfig_declarations: "com.android.server.security.flags-aconfig", + host_supported: true, + test: true, +} diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS index 5bcc98b600fc..f408d7c2efac 100644 --- a/services/core/java/com/android/server/security/OWNERS +++ b/services/core/java/com/android/server/security/OWNERS @@ -1,4 +1,6 @@ # Bug component: 36824 +include /core/java/android/security/OWNERS + per-file *AttestationVerification* = file:/core/java/android/security/attestationverification/OWNERS per-file FileIntegrity*.java = victorhsieh@google.com diff --git a/services/core/java/com/android/server/security/flags.aconfig b/services/core/java/com/android/server/security/flags.aconfig new file mode 100644 index 000000000000..0440989f3981 --- /dev/null +++ b/services/core/java/com/android/server/security/flags.aconfig @@ -0,0 +1,8 @@ +package: "com.android.server.security" + +flag { + name: "deprecate_fsv_sig" + namespace: "hardware_backed_security" + description: "Feature flag for deprecating .fsv_sig" + bug: "277916185" +} 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 5d04e5df6a04..97420d055bd2 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -1599,7 +1599,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1612,7 +1612,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } @@ -1625,7 +1625,7 @@ public class StatsPullAtomService extends SystemService { mStatsManager.setPullAtomCallback( tagId, metadata, - BackgroundThread.getExecutor(), + DIRECT_EXECUTOR, mStatsCallbackImpl ); } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index cc95da57647f..9905ddfbdaa9 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -31,7 +31,6 @@ import android.app.trust.ITrustListener; import android.app.trust.ITrustManager; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -42,11 +41,9 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; -import android.database.ContentObserver; import android.graphics.drawable.Drawable; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricSourceType; -import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -161,9 +158,6 @@ public class TrustManagerService extends SystemService { private final ActivityManager mActivityManager; private VirtualDeviceManagerInternal mVirtualDeviceManager; - @GuardedBy("mUserIsTrusted") - private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); - private enum TrustState { UNTRUSTED, // the phone is not unlocked by any trustagents TRUSTABLE, // the phone is in a semi-locked state that can be unlocked if @@ -224,7 +218,6 @@ public class TrustManagerService extends SystemService { mIdleTrustableTimeoutAlarmListenerForUser = new SparseArray<>(); private AlarmManager mAlarmManager; private final Object mAlarmLock = new Object(); - private final SettingsObserver mSettingsObserver; private final StrongAuthTracker mStrongAuthTracker; @@ -266,7 +259,6 @@ public class TrustManagerService extends SystemService { mLockPatternUtils = injector.getLockPatternUtils(); mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper()); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); - mSettingsObserver = new SettingsObserver(mHandler); } @Override @@ -294,103 +286,10 @@ public class TrustManagerService extends SystemService { } } - // Extend unlock config and logic - private final class SettingsObserver extends ContentObserver { - private final Uri TRUST_AGENTS_EXTEND_UNLOCK = - Settings.Secure.getUriFor(Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK); - - private final Uri LOCK_SCREEN_WHEN_TRUST_LOST = - Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST); - - private final boolean mIsAutomotive; - private final ContentResolver mContentResolver; - private boolean mTrustAgentsNonrenewableTrust; - private boolean mLockWhenTrustLost; - - /** - * Creates a settings observer - * - * @param handler The handler to run {@link #onChange} on, or null if none. - */ - SettingsObserver(Handler handler) { - super(handler); - - PackageManager packageManager = getContext().getPackageManager(); - mIsAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); - - mContentResolver = getContext().getContentResolver(); - updateContentObserver(); - } - - void updateContentObserver() { - mContentResolver.unregisterContentObserver(this); - mContentResolver.registerContentObserver(TRUST_AGENTS_EXTEND_UNLOCK, - false /* notifyForDescendents */, - this /* observer */, - mCurrentUser); - mContentResolver.registerContentObserver(LOCK_SCREEN_WHEN_TRUST_LOST, - false /* notifyForDescendents */, - this /* observer */, - mCurrentUser); - - // Update the value immediately - onChange(true /* selfChange */, TRUST_AGENTS_EXTEND_UNLOCK); - onChange(true /* selfChange */, LOCK_SCREEN_WHEN_TRUST_LOST); - } - - @Override - public void onChange(boolean selfChange, Uri uri) { - if (TRUST_AGENTS_EXTEND_UNLOCK.equals(uri)) { - // Smart lock should only grant non-renewable trust. The only exception is for - // automotive, where it can actively unlock the head unit. - int defaultValue = mIsAutomotive ? 0 : 1; - - mTrustAgentsNonrenewableTrust = - Settings.Secure.getIntForUser( - mContentResolver, - Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK, - defaultValue, - mCurrentUser) != 0; - } else if (LOCK_SCREEN_WHEN_TRUST_LOST.equals(uri)) { - mLockWhenTrustLost = - Settings.Secure.getIntForUser( - mContentResolver, - Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST, - 0 /* default */, - mCurrentUser) != 0; - } - } - - boolean getTrustAgentsNonrenewableTrust() { - return mTrustAgentsNonrenewableTrust; - } - - boolean getLockWhenTrustLost() { - return mLockWhenTrustLost; - } - } - - private void maybeLockScreen(int userId) { - if (userId != mCurrentUser) { - return; - } - - if (mSettingsObserver.getLockWhenTrustLost()) { - if (DEBUG) Slog.d(TAG, "Locking device because trust was lost"); - try { - WindowManagerGlobal.getWindowManagerService().lockNow(null); - } catch (RemoteException e) { - Slog.e(TAG, "Error locking screen when trust was lost"); - } - - // If active unlocking is not allowed, cancel any pending trust timeouts because the - // screen is already locked. - TrustedTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId); - if (alarm != null && mSettingsObserver.getTrustAgentsNonrenewableTrust()) { - mAlarmManager.cancel(alarm); - alarm.setQueued(false /* isQueued */); - } - } + // Automotive head units can be unlocked by a trust agent, even when the agent doesn't use + // FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE. + private boolean isAutomotive() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); } private void scheduleTrustTimeout(boolean override, boolean isTrustableTimeout) { @@ -587,12 +486,10 @@ public class TrustManagerService extends SystemService { synchronized (mUserTrustState) { wasTrusted = (mUserTrustState.get(userId) == TrustState.TRUSTED); wasTrustable = (mUserTrustState.get(userId) == TrustState.TRUSTABLE); - boolean isAutomotive = getContext().getPackageManager().hasSystemFeature( - PackageManager.FEATURE_AUTOMOTIVE); boolean renewingTrust = wasTrustable && ( (flags & TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0); boolean canMoveToTrusted = - alreadyUnlocked || isFromUnlock || renewingTrust || isAutomotive; + alreadyUnlocked || isFromUnlock || renewingTrust || isAutomotive(); boolean upgradingTrustForCurrentUser = (userId == mCurrentUser); if (trustedByAtLeastOneAgent && wasTrusted) { @@ -619,9 +516,7 @@ public class TrustManagerService extends SystemService { isNowTrusted, newlyUnlocked, userId, flags, getTrustGrantedMessages(userId)); if (isNowTrusted != wasTrusted) { refreshDeviceLockedForUser(userId); - if (!isNowTrusted) { - maybeLockScreen(userId); - } else { + if (isNowTrusted) { boolean isTrustableTimeout = (flags & FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0; // Every time we grant renewable trust we should override the idle trustable @@ -1831,9 +1726,7 @@ public class TrustManagerService extends SystemService { synchronized(mUsersUnlockedByBiometric) { mUsersUnlockedByBiometric.put(userId, true); } - // In non-renewable trust mode we need to refresh trust state here, which will call - // refreshDeviceLockedForUser() - int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsNonrenewableTrust() ? 1 : 0; + int updateTrustOnUnlock = isAutomotive() ? 0 : 1; mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId, updateTrustOnUnlock).sendToTarget(); mHandler.obtainMessage(MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH, userId).sendToTarget(); @@ -1942,7 +1835,6 @@ public class TrustManagerService extends SystemService { break; case MSG_SWITCH_USER: mCurrentUser = msg.arg1; - mSettingsObserver.updateContentObserver(); refreshDeviceLockedForUser(UserHandle.USER_ALL); break; case MSG_STOP_USER: @@ -2041,9 +1933,6 @@ public class TrustManagerService extends SystemService { } else if (Intent.ACTION_USER_REMOVED.equals(action)) { int userId = getUserId(intent); if (userId > 0) { - synchronized (mUserIsTrusted) { - mUserIsTrusted.delete(userId); - } synchronized (mDeviceLockedForUser) { mDeviceLockedForUser.delete(userId); } @@ -2175,7 +2064,6 @@ public class TrustManagerService extends SystemService { mLockPatternUtils.requireStrongAuth( mStrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED, mUserId); } - maybeLockScreen(mUserId); } protected abstract void handleAlarm(); diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java index 0ab6d5769b5e..06a851637b82 100755 --- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java +++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java @@ -96,6 +96,8 @@ class TvInputHardwareManager implements TvInputHal.Callback { /* A map from a HDMI logical address to the matching TV input ID. */ private final SparseArray<String> mHdmiInputIdMap = new SparseArray<>(); private final Map<String, TvInputInfo> mInputMap = new ArrayMap<>(); + /* A map from a HDMI input parent ID to the related input IDs. */ + private final Map<String, List<String>> mHdmiParentInputMap = new ArrayMap<>(); private final AudioManager mAudioManager; private final IHdmiHotplugEventListener mHdmiHotplugEventListener = @@ -293,6 +295,12 @@ class TvInputHardwareManager implements TvInputHal.Callback { } } + public Map<String, List<String>> getHdmiParentInputMap() { + synchronized (mLock) { + return Collections.unmodifiableMap(mHdmiParentInputMap); + } + } + private boolean checkUidChangedLocked( Connection connection, int callingUid, int resolvedUserId) { Integer connectionCallingUid = connection.getCallingUidLocked(); @@ -379,12 +387,15 @@ class TvInputHardwareManager implements TvInputHal.Callback { } mHdmiInputIdMap.put(id, info.getId()); mInputMap.put(info.getId(), info); + if (!mHdmiParentInputMap.containsKey(parentId)) { + mHdmiParentInputMap.put(parentId, new ArrayList<String>()); + } + mHdmiParentInputMap.get(parentId).add(info.getId()); } } public void removeHardwareInput(String inputId) { synchronized (mLock) { - mInputMap.remove(inputId); int hardwareIndex = indexOfEqualValue(mHardwareInputIdMap, inputId); if (hardwareIndex >= 0) { mHardwareInputIdMap.removeAt(hardwareIndex); @@ -393,6 +404,17 @@ class TvInputHardwareManager implements TvInputHal.Callback { if (deviceIndex >= 0) { mHdmiInputIdMap.removeAt(deviceIndex); } + if (mInputMap.containsKey(inputId)) { + String parentId = mInputMap.get(inputId).getParentId(); + if (parentId != null && mHdmiParentInputMap.containsKey(parentId)) { + List<String> parentInputList = mHdmiParentInputMap.get(parentId); + parentInputList.remove(inputId); + if (parentInputList.isEmpty()) { + mHdmiParentInputMap.remove(parentId); + } + } + mInputMap.remove(inputId); + } } } diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index 234e3f4c4b54..b12ecc333d1f 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -1839,22 +1839,22 @@ public final class TvInputManagerService extends SystemService { getSessionLocked(sessionToken, callingUid, resolvedUserId).tune( channelUri, params); UserState userState = getOrCreateUserStateLocked(resolvedUserId); - SessionState sessionState = getSessionStateLocked(sessionToken, callingUid, - userState); + SessionState sessionState = + getSessionStateLocked(sessionToken, callingUid, userState); if (!sessionState.isCurrent || !Objects.equals(sessionState.currentChannel, channelUri)) { sessionState.isCurrent = true; sessionState.currentChannel = channelUri; notifyCurrentChannelInfosUpdatedLocked(userState); if (!sessionState.isRecordingSession) { - if (mOnScreenInputId == null - || !TextUtils.equals(mOnScreenInputId, sessionState.inputId)) { + String actualInputId = getActualInputId(sessionState); + if (!TextUtils.equals(mOnScreenInputId, actualInputId)) { logExternalInputEvent( - FrameworkStatsLog - .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED, - sessionState.inputId, sessionState); + FrameworkStatsLog + .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED, + actualInputId, sessionState); } - mOnScreenInputId = sessionState.inputId; + mOnScreenInputId = actualInputId; mOnScreenSessionState = sessionState; } } @@ -2977,6 +2977,31 @@ public final class TvInputManagerService extends SystemService { } } + // get the actual input id of the specific sessionState. + // e.g. if an HDMI port has a CEC device plugged in, the actual input id of the HDMI + // session should be the input id of CEC device instead of the default HDMI input id. + @GuardedBy("mLock") + private String getActualInputId(SessionState sessionState) { + UserState userState = getOrCreateUserStateLocked(sessionState.userId); + TvInputState tvInputState = userState.inputMap.get(sessionState.inputId); + TvInputInfo tvInputInfo = tvInputState.info; + String actualInputId = sessionState.inputId; + switch (tvInputInfo.getType()) { + case TvInputInfo.TYPE_HDMI: + // TODO: find a better approach towards active CEC device in future + Map<String, List<String>> hdmiParentInputMap = + mTvInputHardwareManager.getHdmiParentInputMap(); + if (hdmiParentInputMap.containsKey(sessionState.inputId)) { + List<String> parentInputList = hdmiParentInputMap.get(sessionState.inputId); + actualInputId = parentInputList.get(0); + } + break; + default: + break; + } + return actualInputId; + } + @Nullable private static TvInputState getTvInputState( SessionState sessionState, @@ -3078,6 +3103,7 @@ public final class TvInputManagerService extends SystemService { hdmiPort); } + @GuardedBy("mLock") private void logExternalInputEvent(int eventType, String inputId, SessionState sessionState) { UserState userState = getOrCreateUserStateLocked(sessionState.userId); TvInputState tvInputState = userState.inputMap.get(inputId); @@ -3472,6 +3498,10 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { + ServiceState serviceState = getServiceStateLocked(mComponent, mUserId); + if (serviceState.hardwareInputMap.containsKey(inputInfo.getId())) { + return; + } mTvInputHardwareManager.addHardwareInput(deviceId, inputInfo); addHardwareInputLocked(inputInfo); } @@ -3486,6 +3516,10 @@ public final class TvInputManagerService extends SystemService { final long identity = Binder.clearCallingIdentity(); try { synchronized (mLock) { + ServiceState serviceState = getServiceStateLocked(mComponent, mUserId); + if (serviceState.hardwareInputMap.containsKey(inputInfo.getId())) { + return; + } mTvInputHardwareManager.addHdmiInput(id, inputInfo); addHardwareInputLocked(inputInfo); if (mOnScreenInputId != null && mOnScreenSessionState != null) { @@ -3609,13 +3643,14 @@ public final class TvInputManagerService extends SystemService { mSessionState.currentChannel = channelUri; notifyCurrentChannelInfosUpdatedLocked(userState); if (!mSessionState.isRecordingSession) { - if (mOnScreenInputId == null - || !TextUtils.equals(mOnScreenInputId, mSessionState.inputId)) { + String actualInputId = getActualInputId(mSessionState); + if (!TextUtils.equals(mOnScreenInputId, actualInputId)) { logExternalInputEvent( - FrameworkStatsLog.EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED, - mSessionState.inputId, mSessionState); + FrameworkStatsLog + .EXTERNAL_TV_INPUT_EVENT__EVENT_TYPE__TUNED, + actualInputId, mSessionState); } - mOnScreenInputId = mSessionState.inputId; + mOnScreenInputId = actualInputId; mOnScreenSessionState = mSessionState; } } diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java index 3fb845f064e3..e4f960763d54 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java @@ -19,7 +19,7 @@ package com.android.server.vibrator; import android.annotation.Nullable; import android.content.res.Resources; import android.os.VibrationEffect; -import android.os.Vibrator; +import android.os.VibratorInfo; import android.os.vibrator.persistence.ParsedVibration; import android.os.vibrator.persistence.VibrationXmlParser; import android.text.TextUtils; @@ -107,10 +107,10 @@ final class HapticFeedbackCustomization { * @hide */ @Nullable - static SparseArray<VibrationEffect> loadVibrations(Resources res, Vibrator vibrator) + static SparseArray<VibrationEffect> loadVibrations(Resources res, VibratorInfo vibratorInfo) throws CustomizationParserException, IOException { try { - return loadVibrationsInternal(res, vibrator); + return loadVibrationsInternal(res, vibratorInfo); } catch (VibrationXmlParser.VibrationXmlParserException | XmlParserException | XmlPullParserException e) { @@ -121,7 +121,7 @@ final class HapticFeedbackCustomization { @Nullable private static SparseArray<VibrationEffect> loadVibrationsInternal( - Resources res, Vibrator vibrator) throws + Resources res, VibratorInfo vibratorInfo) throws CustomizationParserException, IOException, VibrationXmlParser.VibrationXmlParserException, @@ -175,7 +175,7 @@ final class HapticFeedbackCustomization { throw new CustomizationParserException( "Unable to parse vibration element for effect " + effectId); } - VibrationEffect effect = parsedVibration.resolve(vibrator); + VibrationEffect effect = parsedVibration.resolve(vibratorInfo); if (effect != null) { if (effect.getDuration() == Long.MAX_VALUE) { throw new CustomizationParserException(String.format( diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java index 7c9954391d8c..3d89afaae88f 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java @@ -21,6 +21,7 @@ import android.content.res.Resources; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; +import android.os.VibratorInfo; import android.util.Slog; import android.util.SparseArray; import android.view.HapticFeedbackConstants; @@ -29,8 +30,6 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.IOException; import java.io.PrintWriter; -import java.util.HashSet; -import java.util.Set; /** * Provides the {@link VibrationEffect} and {@link VibrationAttributes} for haptic feedback. @@ -47,7 +46,7 @@ public final class HapticFeedbackVibrationProvider { private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); - private final Vibrator mVibrator; + private final VibratorInfo mVibratorInfo; private final boolean mHapticTextHandleEnabled; // Vibrator effect for haptic feedback during boot when safe mode is enabled. private final VibrationEffect mSafeModeEnabledVibrationEffect; @@ -58,25 +57,25 @@ public final class HapticFeedbackVibrationProvider { /** @hide */ public HapticFeedbackVibrationProvider(Resources res, Vibrator vibrator) { - this(res, vibrator, loadHapticCustomizations(res, vibrator)); + this(res, vibrator.getInfo()); + } + + /** @hide */ + public HapticFeedbackVibrationProvider(Resources res, VibratorInfo vibratorInfo) { + this(res, vibratorInfo, loadHapticCustomizations(res, vibratorInfo)); } /** @hide */ @VisibleForTesting HapticFeedbackVibrationProvider( Resources res, - Vibrator vibrator, + VibratorInfo vibratorInfo, @Nullable SparseArray<VibrationEffect> hapticCustomizations) { - mVibrator = vibrator; + mVibratorInfo = vibratorInfo; mHapticTextHandleEnabled = res.getBoolean( com.android.internal.R.bool.config_enableHapticTextHandle); - if (hapticCustomizations != null) { - // Clean up the customizations to remove vibrations which may not ever be used due to - // Vibrator properties or other device configurations. - removeUnsupportedVibrations(hapticCustomizations, vibrator); - if (hapticCustomizations.size() == 0) { - hapticCustomizations = null; - } + if (hapticCustomizations != null && hapticCustomizations.size() == 0) { + hapticCustomizations = null; } mHapticCustomizations = hapticCustomizations; @@ -257,7 +256,7 @@ public final class HapticFeedbackVibrationProvider { if (effectHasCustomization(hapticFeedbackId)) { return mHapticCustomizations.get(hapticFeedbackId); } - if (mVibrator.areAllPrimitivesSupported(primitiveId)) { + if (mVibratorInfo.isPrimitiveSupported(primitiveId)) { return VibrationEffect.startComposition() .addPrimitive(primitiveId, primitiveScale) .compose(); @@ -270,9 +269,8 @@ public final class HapticFeedbackVibrationProvider { if (effectHasCustomization(HapticFeedbackConstants.ASSISTANT_BUTTON)) { return mHapticCustomizations.get(HapticFeedbackConstants.ASSISTANT_BUTTON); } - if (mVibrator.areAllPrimitivesSupported( - VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, - VibrationEffect.Composition.PRIMITIVE_TICK)) { + if (mVibratorInfo.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE) + && mVibratorInfo.isPrimitiveSupported(VibrationEffect.Composition.PRIMITIVE_TICK)) { // quiet ramp, short pause, then sharp tick return VibrationEffect.startComposition() .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f) @@ -289,27 +287,12 @@ public final class HapticFeedbackVibrationProvider { @Nullable private static SparseArray<VibrationEffect> loadHapticCustomizations( - Resources res, Vibrator vibrator) { + Resources res, VibratorInfo vibratorInfo) { try { - return HapticFeedbackCustomization.loadVibrations(res, vibrator); + return HapticFeedbackCustomization.loadVibrations(res, vibratorInfo); } catch (IOException | HapticFeedbackCustomization.CustomizationParserException e) { Slog.e(TAG, "Unable to load haptic customizations.", e); return null; } } - - private static void removeUnsupportedVibrations( - SparseArray<VibrationEffect> customizations, Vibrator vibrator) { - Set<Integer> keysToRemove = new HashSet<>(); - for (int i = 0; i < customizations.size(); i++) { - int key = customizations.keyAt(i); - if (!vibrator.areVibrationFeaturesSupported(customizations.get(key))) { - keysToRemove.add(key); - } - } - - for (int key : keysToRemove) { - customizations.remove(key); - } - } } diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java index e296c7b764e5..ee3d697cddb8 100644 --- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java +++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.hardware.vibrator.IVibrator; import android.os.BatteryStats; import android.os.Binder; @@ -131,6 +132,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { private final Object mLock = new Object(); private final Context mContext; + private final Injector mInjector; private final PowerManager.WakeLock mWakeLock; private final IBatteryStats mBatteryStatsService; private final VibratorFrameworkStatsLogger mFrameworkStatsLogger; @@ -162,6 +164,8 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @GuardedBy("mLock") @Nullable private VibratorInfo mCombinedVibratorInfo; + @GuardedBy("mLock") + @Nullable private HapticFeedbackVibrationProvider mHapticFeedbackVibrationProvider; private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override @@ -201,6 +205,7 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @VisibleForTesting VibratorManagerService(Context context, Injector injector) { mContext = context; + mInjector = injector; mHandler = injector.createHandler(Looper.myLooper()); mVibrationSettings = new VibrationSettings(mContext, mHandler); @@ -393,7 +398,42 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { @Override // Binder call public void vibrate(int uid, int displayId, String opPkg, @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs, String reason, IBinder token) { - vibrateInternal(uid, displayId, opPkg, effect, attrs, reason, token); + vibrateWithPermissionCheck(uid, displayId, opPkg, effect, attrs, reason, token); + } + + @Override // Binder call + public void performHapticFeedback( + int uid, int displayId, String opPkg, int constant, boolean always, String reason, + IBinder token) { + performHapticFeedbackInternal(uid, displayId, opPkg, constant, always, reason, token); + } + + /** + * An internal-only version of performHapticFeedback that allows the caller access to the + * {@link HalVibration}. + * The Vibration is only returned if it is ongoing after this method returns. + */ + @VisibleForTesting + @Nullable + HalVibration performHapticFeedbackInternal( + int uid, int displayId, String opPkg, int constant, boolean always, String reason, + IBinder token) { + HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider(); + if (hapticVibrationProvider == null) { + Slog.w(TAG, "performHapticFeedback; haptic vibration provider not ready."); + return null; + } + VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant); + if (effect == null) { + Slog.w(TAG, "performHapticFeedback; vibration absent for effect " + constant); + return null; + } + CombinedVibration combinedVibration = CombinedVibration.createParallel(effect); + VibrationAttributes attrs = + hapticVibrationProvider.getVibrationAttributesForHapticFeedback( + constant, /* bypassVibrationIntensitySetting= */ always); + return vibrateWithoutPermissionCheck(uid, displayId, opPkg, combinedVibration, attrs, + "performHapticFeedback: " + reason, token); } /** @@ -403,90 +443,107 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { */ @VisibleForTesting @Nullable - HalVibration vibrateInternal(int uid, int displayId, String opPkg, + HalVibration vibrateWithPermissionCheck(int uid, int displayId, String opPkg, @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs, String reason, IBinder token) { Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason); try { - mContext.enforceCallingOrSelfPermission(android.Manifest.permission.VIBRATE, "vibrate"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.VIBRATE, "vibrate"); + return vibrateInternal(uid, displayId, opPkg, effect, attrs, reason, token); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); + } + } - if (token == null) { - Slog.e(TAG, "token must not be null"); - return null; - } - enforceUpdateAppOpsStatsPermission(uid); - if (!isEffectValid(effect)) { - return null; - } - attrs = fixupVibrationAttributes(attrs, effect); - // Create Vibration.Stats as close to the received request as possible, for tracking. - HalVibration vib = new HalVibration(token, effect, - new Vibration.CallerInfo(attrs, uid, displayId, opPkg, reason)); - fillVibrationFallbacks(vib, effect); + HalVibration vibrateWithoutPermissionCheck(int uid, int displayId, String opPkg, + @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs, + String reason, IBinder token) { + Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate no perm check, reason = " + reason); + try { + return vibrateInternal(uid, displayId, opPkg, effect, attrs, reason, token); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); + } + } - if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { - // Force update of user settings before checking if this vibration effect should - // be ignored or scaled. - mVibrationSettings.update(); - } + private HalVibration vibrateInternal(int uid, int displayId, String opPkg, + @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs, + String reason, IBinder token) { + if (token == null) { + Slog.e(TAG, "token must not be null"); + return null; + } + enforceUpdateAppOpsStatsPermission(uid); + if (!isEffectValid(effect)) { + return null; + } + attrs = fixupVibrationAttributes(attrs, effect); + // Create Vibration.Stats as close to the received request as possible, for tracking. + HalVibration vib = new HalVibration(token, effect, + new Vibration.CallerInfo(attrs, uid, displayId, opPkg, reason)); + fillVibrationFallbacks(vib, effect); - synchronized (mLock) { - if (DEBUG) { - Slog.d(TAG, "Starting vibrate for vibration " + vib.id); - } + if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) { + // Force update of user settings before checking if this vibration effect should + // be ignored or scaled. + mVibrationSettings.update(); + } - // Check if user settings or DnD is set to ignore this vibration. - Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationLocked(vib.callerInfo); + synchronized (mLock) { + if (DEBUG) { + Slog.d(TAG, "Starting vibrate for vibration " + vib.id); + } - // Check if ongoing vibration is more important than this vibration. - if (vibrationEndInfo == null) { - vibrationEndInfo = shouldIgnoreVibrationForOngoingLocked(vib); - } + // Check if user settings or DnD is set to ignore this vibration. + Vibration.EndInfo vibrationEndInfo = shouldIgnoreVibrationLocked(vib.callerInfo); - // If not ignored so far then try to start this vibration. - if (vibrationEndInfo == null) { - final long ident = Binder.clearCallingIdentity(); - try { - if (mCurrentExternalVibration != null) { - mCurrentExternalVibration.mute(); + // Check if ongoing vibration is more important than this vibration. + if (vibrationEndInfo == null) { + vibrationEndInfo = shouldIgnoreVibrationForOngoingLocked(vib); + } + + // If not ignored so far then try to start this vibration. + if (vibrationEndInfo == null) { + final long ident = Binder.clearCallingIdentity(); + try { + if (mCurrentExternalVibration != null) { + mCurrentExternalVibration.mute(); + vib.stats.reportInterruptedAnotherVibration( + mCurrentExternalVibration.callerInfo); + endExternalVibrateLocked( + new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED, + vib.callerInfo), + /* continueExternalControl= */ false); + } else if (mCurrentVibration != null) { + if (mCurrentVibration.getVibration().canPipelineWith(vib)) { + // Don't cancel the current vibration if it's pipeline-able. + // Note that if there is a pending next vibration that can't be + // pipelined, it will have already cancelled the current one, so we + // don't need to consider it here as well. + if (DEBUG) { + Slog.d(TAG, "Pipelining vibration " + vib.id); + } + } else { vib.stats.reportInterruptedAnotherVibration( - mCurrentExternalVibration.callerInfo); - endExternalVibrateLocked( + mCurrentVibration.getVibration().callerInfo); + mCurrentVibration.notifyCancelled( new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED, vib.callerInfo), - /* continueExternalControl= */ false); - } else if (mCurrentVibration != null) { - if (mCurrentVibration.getVibration().canPipelineWith(vib)) { - // Don't cancel the current vibration if it's pipeline-able. - // Note that if there is a pending next vibration that can't be - // pipelined, it will have already cancelled the current one, so we - // don't need to consider it here as well. - if (DEBUG) { - Slog.d(TAG, "Pipelining vibration " + vib.id); - } - } else { - vib.stats.reportInterruptedAnotherVibration( - mCurrentVibration.getVibration().callerInfo); - mCurrentVibration.notifyCancelled( - new Vibration.EndInfo(Vibration.Status.CANCELLED_SUPERSEDED, - vib.callerInfo), - /* immediate= */ false); - } + /* immediate= */ false); } - vibrationEndInfo = startVibrationLocked(vib); - } finally { - Binder.restoreCallingIdentity(ident); } + vibrationEndInfo = startVibrationLocked(vib); + } finally { + Binder.restoreCallingIdentity(ident); } + } - // Ignored or failed to start the vibration, end it and report metrics right away. - if (vibrationEndInfo != null) { - endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ true); - } - return vib; + // Ignored or failed to start the vibration, end it and report metrics right away. + if (vibrationEndInfo != null) { + endVibrationLocked(vib, vibrationEndInfo, /* shouldWriteStats= */ true); } - } finally { - Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); + return vib; } } @@ -1315,6 +1372,11 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return new VibratorController(vibratorId, listener); } + HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider( + Resources resources, VibratorInfo vibratorInfo) { + return new HapticFeedbackVibrationProvider(resources, vibratorInfo); + } + void addService(String name, IBinder service) { ServiceManager.addService(name, service); } @@ -1831,6 +1893,22 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } + private HapticFeedbackVibrationProvider getHapticVibrationProvider() { + synchronized (mLock) { + // Used a cached haptic vibration provider if one exists. + if (mHapticFeedbackVibrationProvider != null) { + return mHapticFeedbackVibrationProvider; + } + VibratorInfo combinedVibratorInfo = getCombinedVibratorInfo(); + if (combinedVibratorInfo == null) { + return null; + } + return mHapticFeedbackVibrationProvider = + mInjector.createHapticFeedbackVibrationProvider( + mContext.getResources(), combinedVibratorInfo); + } + } + private VibratorInfo getCombinedVibratorInfo() { synchronized (mLock) { // Used a cached resolving vibrator if one exists. @@ -2068,6 +2146,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { if ("cancel".equals(cmd)) { return runCancel(); } + if ("feedback".equals(cmd)) { + return runHapticFeedback(); + } return handleDefaultCommands(cmd); } finally { Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR); @@ -2098,16 +2179,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { // only cancel background vibrations. IBinder deathBinder = commonOptions.background ? VibratorManagerService.this : mShellCallbacksToken; - HalVibration vib = vibrateInternal(Binder.getCallingUid(), Display.DEFAULT_DISPLAY, - SHELL_PACKAGE_NAME, combined, attrs, commonOptions.description, deathBinder); - if (vib != null && !commonOptions.background) { - try { - // Waits for the client vibration to finish, but the VibrationThread may still - // do cleanup after this. - vib.waitForEnd(); - } catch (InterruptedException e) { - } - } + HalVibration vib = vibrateWithPermissionCheck(Binder.getCallingUid(), + Display.DEFAULT_DISPLAY, SHELL_PACKAGE_NAME, combined, attrs, + commonOptions.description, deathBinder); + maybeWaitOnVibration(vib, commonOptions); } private int runMono() { @@ -2155,6 +2230,21 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { return 0; } + private int runHapticFeedback() { + CommonOptions commonOptions = new CommonOptions(); + int constant = Integer.parseInt(getNextArgRequired()); + + IBinder deathBinder = commonOptions.background ? VibratorManagerService.this + : mShellCallbacksToken; + HalVibration vib = performHapticFeedbackInternal(Binder.getCallingUid(), + Display.DEFAULT_DISPLAY, SHELL_PACKAGE_NAME, constant, + /* always= */ commonOptions.force, /* reason= */ commonOptions.description, + deathBinder); + maybeWaitOnVibration(vib, commonOptions); + + return 0; + } + private VibrationEffect nextEffect() { VibrationEffect.Composition composition = VibrationEffect.startComposition(); String nextArg; @@ -2364,6 +2454,17 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { } } + private void maybeWaitOnVibration(HalVibration vib, CommonOptions commonOptions) { + if (vib != null && !commonOptions.background) { + try { + // Waits for the client vibration to finish, but the VibrationThread may still + // do cleanup after this. + vib.waitForEnd(); + } catch (InterruptedException e) { + } + } + } + @Override public void onHelp() { try (PrintWriter pw = getOutPrintWriter();) { @@ -2389,6 +2490,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub { pw.println(" XML containing a single effect it runs on all vibrators in sync."); pw.println(" cancel"); pw.println(" Cancels any active vibration"); + pw.println(" feedback [-f] [-d <description>] <constant>"); + pw.println(" Performs a haptic feedback with the given constant."); + pw.println(" The force (-f) option enables the `always` configuration, which"); + pw.println(" plays the haptic irrespective of the vibration intensity settings"); pw.println(""); pw.println("Effect commands:"); pw.println(" oneshot [-w delay] [-a] <duration> [<amplitude>]"); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 60854885d5bb..582536b662ce 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -2929,7 +2929,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A reparent(newTaskFrag, position); } - private boolean isHomeIntent(Intent intent) { + static boolean isHomeIntent(Intent intent) { return ACTION_MAIN.equals(intent.getAction()) && (intent.hasCategory(CATEGORY_HOME) || intent.hasCategory(CATEGORY_SECONDARY_HOME)) @@ -3363,7 +3363,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // current focused activity could be another activity in the same Task if activities are // displayed on adjacent TaskFragments. final ActivityRecord currentFocusedApp = mDisplayContent.mFocusedApp; - if (currentFocusedApp != null && currentFocusedApp.task == task) { + final int topFocusedDisplayId = mRootWindowContainer.getTopFocusedDisplayContent() != null + ? mRootWindowContainer.getTopFocusedDisplayContent().getDisplayId() + : INVALID_DISPLAY; + if (currentFocusedApp != null && currentFocusedApp.task == task + && topFocusedDisplayId == mDisplayContent.getDisplayId()) { final Task topFocusableTask = mDisplayContent.getTask( (t) -> t.isLeafTask() && t.isFocusable(), true /* traverseTopToBottom */); if (task == topFocusableTask) { diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java index 1eb56f1b7d1c..a5b1132fe499 100644 --- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java +++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java @@ -55,6 +55,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import android.util.Pair; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; @@ -77,7 +78,6 @@ class ActivityStartInterceptor { private final ActivityTaskManagerService mService; private final ActivityTaskSupervisor mSupervisor; - private final RootWindowContainer mRootWindowContainer; private final Context mServiceContext; // UserManager cannot be final as it's not ready when this class is instantiated during boot @@ -110,17 +110,23 @@ class ActivityStartInterceptor { TaskFragment mInTaskFragment; ActivityOptions mActivityOptions; + /* + * Note that this is just a hint of what the launch display area will be as it is + * based only on the information at the early pre-interception stage of starting the + * intent. The real launch display area calculated later may be different from this one. + */ + TaskDisplayArea mPresumableLaunchDisplayArea; + ActivityStartInterceptor( ActivityTaskManagerService service, ActivityTaskSupervisor supervisor) { - this(service, supervisor, service.mRootWindowContainer, service.mContext); + this(service, supervisor, service.mContext); } @VisibleForTesting ActivityStartInterceptor(ActivityTaskManagerService service, ActivityTaskSupervisor supervisor, - RootWindowContainer root, Context context) { + Context context) { mService = service; mSupervisor = supervisor; - mRootWindowContainer = root; mServiceContext = context; } @@ -162,7 +168,7 @@ class ActivityStartInterceptor { /** * A helper function to obtain the targeted {@link TaskFragment} during * {@link #intercept(Intent, ResolveInfo, ActivityInfo, String, Task, TaskFragment, int, int, - * ActivityOptions)} if any. + * ActivityOptions, TaskDisplayArea)} if any. */ @Nullable private TaskFragment getLaunchTaskFragment() { @@ -187,7 +193,7 @@ class ActivityStartInterceptor { */ boolean intercept(Intent intent, ResolveInfo rInfo, ActivityInfo aInfo, String resolvedType, Task inTask, TaskFragment inTaskFragment, int callingPid, int callingUid, - ActivityOptions activityOptions) { + ActivityOptions activityOptions, TaskDisplayArea presumableLaunchDisplayArea) { mUserManager = UserManager.get(mServiceContext); mIntent = intent; @@ -199,6 +205,7 @@ class ActivityStartInterceptor { mInTask = inTask; mInTaskFragment = inTaskFragment; mActivityOptions = activityOptions; + mPresumableLaunchDisplayArea = presumableLaunchDisplayArea; if (interceptQuietProfileIfNeeded()) { // If work profile is turned off, skip the work challenge since the profile can only @@ -221,6 +228,11 @@ class ActivityStartInterceptor { if (interceptLockedManagedProfileIfNeeded()) { return true; } + if (interceptHomeIfNeeded()) { + // Replace primary home intents directed at displays that do not support primary home + // but support secondary home with the relevant secondary home activity. + return true; + } final SparseArray<ActivityInterceptorCallback> callbacks = mService.getActivityInterceptorCallbacks(); @@ -470,6 +482,47 @@ class ActivityStartInterceptor { return true; } + private boolean interceptHomeIfNeeded() { + if (mPresumableLaunchDisplayArea == null || mService.mRootWindowContainer == null) { + return false; + } + if (!ActivityRecord.isHomeIntent(mIntent)) { + return false; + } + if (!mIntent.hasCategory(Intent.CATEGORY_HOME)) { + // Already a secondary home intent, leave it alone. + return false; + } + if (mService.mRootWindowContainer.shouldPlacePrimaryHomeOnDisplay( + mPresumableLaunchDisplayArea.getDisplayId())) { + // Primary home can be launched to the display area. + return false; + } + if (!mService.mRootWindowContainer.shouldPlaceSecondaryHomeOnDisplayArea( + mPresumableLaunchDisplayArea)) { + // Secondary home cannot be launched on the display area. + return false; + } + + // At this point we have a primary home intent for a display that does not support primary + // home activity but it supports secondary home one. So replace it with secondary home. + Pair<ActivityInfo, Intent> info = mService.mRootWindowContainer + .resolveSecondaryHomeActivity(mUserId, mPresumableLaunchDisplayArea); + mIntent = info.second; + // The new task flag is needed because the home activity should already be in the root task + // and should not be moved to the caller's task. Also, activities cannot change their type, + // e.g. a standard activity cannot become a home activity. + mIntent.addFlags(FLAG_ACTIVITY_NEW_TASK); + mCallingPid = mRealCallingPid; + mCallingUid = mRealCallingUid; + mResolvedType = null; + + mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, mUserId, /* flags= */ 0, + mRealCallingUid, mRealCallingPid); + mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, /*profilerInfo=*/ null); + return true; + } + private boolean isPackageSuspended() { return mAInfo != null && mAInfo.applicationInfo != null && (mAInfo.applicationInfo.flags & FLAG_SUSPENDED) != 0; diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 1bc78d6e0820..458d1e8fa04b 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1154,10 +1154,12 @@ class ActivityStarter { } } + final TaskDisplayArea suggestedLaunchDisplayArea = + computeSuggestedLaunchDisplayArea(inTask, sourceRecord, checkedOptions); mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage, callingFeatureId); if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment, - callingPid, callingUid, checkedOptions)) { + callingPid, callingUid, checkedOptions, suggestedLaunchDisplayArea)) { // activity start was intercepted, e.g. because the target user is currently in quiet // mode (turn off work) or the target application is suspended intent = mInterceptor.mIntent; @@ -1890,6 +1892,15 @@ class ActivityStarter { mPreferredWindowingMode = mLaunchParams.mWindowingMode; } + private TaskDisplayArea computeSuggestedLaunchDisplayArea( + Task task, ActivityRecord source, ActivityOptions options) { + mSupervisor.getLaunchParamsController().calculate(task, /*layout=*/null, + /*activity=*/ null, source, options, mRequest, PHASE_DISPLAY, mLaunchParams); + return mLaunchParams.hasPreferredTaskDisplayArea() + ? mLaunchParams.mPreferredTaskDisplayArea + : mRootWindowContainer.getDefaultTaskDisplayArea(); + } + @VisibleForTesting int isAllowedToStart(ActivityRecord r, boolean newTask, Task targetTask) { if (r.packageName == null) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 42c363085017..fd42077bed7d 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -2648,9 +2648,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mAmInternal.enforceCallingPermission(Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, "updateLockTaskPackages()"); } - synchronized (mGlobalLock) { - ProtoLog.w(WM_DEBUG_LOCKTASK, "Allowlisting %d:%s", userId, Arrays.toString(packages)); - getLockTaskController().updateLockTaskPackages(userId, packages); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + ProtoLog.w(WM_DEBUG_LOCKTASK, "Allowlisting %d:%s", userId, + Arrays.toString(packages)); + getLockTaskController().updateLockTaskPackages(userId, packages); + } + } finally { + Binder.restoreCallingIdentity(origId); } } @@ -6177,6 +6183,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void onPackageReplaced(ApplicationInfo aInfo) { synchronized (mGlobalLock) { + // In case if setWindowManager hasn't been called yet when booting. + if (mRootWindowContainer == null) return; mRootWindowContainer.updateActivityApplicationInfo(aInfo); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2e51fe410f46..334464c8a503 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -6519,10 +6519,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } /** - * @return whether the physical display has a fixed orientation and cannot be rotated. + * @return whether the physical display orientation should change when its content rotates to + * match the orientation of the content. */ - boolean isDisplayOrientationFixed() { - return (mDisplayInfo.flags & Display.FLAG_ROTATES_WITH_CONTENT) == 0; + boolean shouldRotateWithContent() { + return (mDisplayInfo.flags & Display.FLAG_ROTATES_WITH_CONTENT) != 0; } /** diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 9ef25b6e71b1..315c479cda30 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -435,7 +435,7 @@ public class DisplayRotation { PackageManager.FEATURE_LEANBACK); mDefaultFixedToUserRotation = (isCar || isTv || mService.mIsPc || mDisplayContent.forceDesktopMode() - || mDisplayContent.isDisplayOrientationFixed()) + || !mDisplayContent.shouldRotateWithContent()) // For debug purposes the next line turns this feature off with: // $ adb shell setprop config.override_forced_orient true // $ adb shell wm size reset diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java index 2fb98690f661..6b33746ad3c4 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java +++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java @@ -68,19 +68,15 @@ class DisplayWindowPolicyControllerHelper { } /** - * @see DisplayWindowPolicyController#canContainActivities(List, int) + * @see DisplayWindowPolicyController#canContainActivities */ public boolean canContainActivities(@NonNull List<ActivityInfo> activities, @WindowConfiguration.WindowingMode int windowingMode) { if (mDisplayWindowPolicyController == null) { - for (int i = activities.size() - 1; i >= 0; i--) { - final ActivityInfo aInfo = activities.get(i); - if (aInfo.requiredDisplayCategory != null) { - Slog.e(TAG, - String.format("Activity with requiredDisplayCategory='%s' cannot be" - + " displayed on display %d because that display does" - + " not have a matching category", - aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); + for (int i = 0; i < activities.size(); ++i) { + // Missing controller means that this display has no categories for activity launch + // restriction. + if (hasDisplayCategory(activities.get(i))) { return false; } } @@ -90,26 +86,31 @@ class DisplayWindowPolicyControllerHelper { } /** - * @see DisplayWindowPolicyController#canActivityBeLaunched(ActivityInfo, int, int, boolean) + * @see DisplayWindowPolicyController#canActivityBeLaunched */ public boolean canActivityBeLaunched(ActivityInfo activityInfo, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { if (mDisplayWindowPolicyController == null) { - if (activityInfo.requiredDisplayCategory != null) { - Slog.e(TAG, - String.format("Activity with requiredDisplayCategory='%s' cannot be" - + " launched on display %d because that display does" - + " not have a matching category", - activityInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); - return false; - } - return true; + // Missing controller means that this display has no categories for activity launch + // restriction. + return !hasDisplayCategory(activityInfo); } return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent, windowingMode, launchingFromDisplayId, isNewTask); } + private boolean hasDisplayCategory(ActivityInfo aInfo) { + if (aInfo.requiredDisplayCategory != null) { + Slog.d(TAG, + String.format("Checking activity launch with requiredDisplayCategory='%s' on" + + " display %d, which doesn't have a matching category.", + aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId)); + return true; + } + return false; + } + /** * @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int) */ @@ -199,7 +200,6 @@ class DisplayWindowPolicyControllerHelper { return mDisplayWindowPolicyController.isEnteringPipAllowed(uid); } - void dump(String prefix, PrintWriter pw) { if (mDisplayWindowPolicyController != null) { pw.println(); diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 9e3a611c0e70..97b3e3280f2b 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -880,6 +880,58 @@ final class LetterboxConfiguration { false /* forTabletopMode */); } + /** + * Overrides persistent horizontal position of the letterboxed app window when horizontal + * reachability is enabled. + */ + void setPersistentLetterboxPositionForHorizontalReachability(boolean forBookMode, + @LetterboxHorizontalReachabilityPosition int position) { + mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability( + forBookMode, position); + } + + /** + * Overrides persistent vertical position of the letterboxed app window when vertical + * reachability is enabled. + */ + void setPersistentLetterboxPositionForVerticalReachability(boolean forTabletopMode, + @LetterboxVerticalReachabilityPosition int position) { + mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability( + forTabletopMode, position); + } + + /** + * Resets persistent horizontal position of the letterboxed app window when horizontal + * reachability + * is enabled to default position. + */ + void resetPersistentLetterboxPositionForHorizontalReachability() { + mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability( + false /* forBookMode */, + readLetterboxHorizontalReachabilityPositionFromConfig(mContext, + false /* forBookMode */)); + mLetterboxConfigurationPersister.setLetterboxPositionForHorizontalReachability( + true /* forBookMode */, + readLetterboxHorizontalReachabilityPositionFromConfig(mContext, + true /* forBookMode */)); + } + + /** + * Resets persistent vertical position of the letterboxed app window when vertical reachability + * is + * enabled to default position. + */ + void resetPersistentLetterboxPositionForVerticalReachability() { + mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability( + false /* forTabletopMode */, + readLetterboxVerticalReachabilityPositionFromConfig(mContext, + false /* forTabletopMode */)); + mLetterboxConfigurationPersister.setLetterboxPositionForVerticalReachability( + true /* forTabletopMode */, + readLetterboxVerticalReachabilityPositionFromConfig(mContext, + true /* forTabletopMode */)); + } + @LetterboxHorizontalReachabilityPosition private static int readLetterboxHorizontalReachabilityPositionFromConfig(Context context, boolean forBookMode) { diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java index e646f14a3e13..106e142cc342 100644 --- a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java +++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java @@ -21,6 +21,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION import android.annotation.NonNull; import android.annotation.Nullable; import android.os.RemoteException; +import android.os.Trace; import android.util.Slog; import android.view.IDisplayChangeWindowCallback; import android.window.DisplayAreaInfo; @@ -40,6 +41,7 @@ import java.util.List; public class RemoteDisplayChangeController { private static final String TAG = "RemoteDisplayChangeController"; + private static final String REMOTE_DISPLAY_CHANGE_TRACE_TAG = "RemoteDisplayChange"; private static final int REMOTE_DISPLAY_CHANGE_TIMEOUT_MS = 800; @@ -82,6 +84,10 @@ public class RemoteDisplayChangeController { } mCallbacks.add(callback); + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.beginAsyncSection(REMOTE_DISPLAY_CHANGE_TRACE_TAG, callback.hashCode()); + } + if (newDisplayAreaInfo != null) { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting remote display change: " @@ -122,6 +128,10 @@ public class RemoteDisplayChangeController { mCallbacks.clear(); } callback.onContinueRemoteDisplayChange(null /* transaction */); + + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.endAsyncSection(REMOTE_DISPLAY_CHANGE_TRACE_TAG, callback.hashCode()); + } } } } @@ -137,13 +147,23 @@ public class RemoteDisplayChangeController { for (int i = 0; i < idx; ++i) { // Expect remote callbacks in order. If they don't come in order, then force // ordering by continuing everything up until this one with empty transactions. - mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */); + ContinueRemoteDisplayChangeCallback currentCallback = mCallbacks.get(i); + currentCallback.onContinueRemoteDisplayChange(null /* transaction */); + + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.endAsyncSection(REMOTE_DISPLAY_CHANGE_TRACE_TAG, + currentCallback.hashCode()); + } } mCallbacks.subList(0, idx + 1).clear(); if (mCallbacks.isEmpty()) { mService.mH.removeCallbacks(mTimeoutRunnable); } callback.onContinueRemoteDisplayChange(transaction); + + if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) { + Trace.endAsyncSection(REMOTE_DISPLAY_CHANGE_TRACE_TAG, callback.hashCode()); + } } } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 57f8268b2fdc..d56acaa00f00 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -1608,6 +1608,19 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } /** + * Check if the display is valid for primary home activity. + * + * @param displayId The target display ID + * @return {@code true} if allowed to launch, {@code false} otherwise. + */ + boolean shouldPlacePrimaryHomeOnDisplay(int displayId) { + // No restrictions to default display, vr 2d display or main display for visible users. + return displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY + && (displayId == mService.mVr2dDisplayId + || mWmService.shouldPlacePrimaryHomeOnDisplay(displayId))); + } + + /** * Check if the display area is valid for secondary home activity. * * @param taskDisplayArea The target display area. @@ -1680,10 +1693,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> final int displayId = taskDisplayArea != null ? taskDisplayArea.getDisplayId() : INVALID_DISPLAY; - if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY - && (displayId == mService.mVr2dDisplayId - || mWmService.shouldPlacePrimaryHomeOnDisplay(displayId)))) { - // No restrictions to default display, vr 2d display or main display for visible users. + if (shouldPlacePrimaryHomeOnDisplay(displayId)) { return true; } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 387a8767ced3..21a4fe880ab6 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2815,7 +2815,7 @@ class Task extends TaskFragment { final WindowManager.LayoutParams attrs = win.mAttrs; visibleFrame.set(win.getFrame()); visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets( - visibleFrame, attrs.type, win.getWindowingMode(), attrs.softInputMode, + visibleFrame, attrs.type, win.getActivityType(), attrs.softInputMode, attrs.flags)); out.union(visibleFrame); } diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index ad46770432a1..4e7a9bd2881a 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -118,12 +118,14 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { root = activity; } - if (root == null) { + if (root == null && phase != PHASE_DISPLAY) { // There is a case that can lead us here. The caller is moving the top activity that is // in a task that has multiple activities to PIP mode. For that the caller is creating a // new task to host the activity so that we only move the top activity to PIP mode and // keep other activities in the previous task. There is no point to apply the launch // logic in this case. + // However, for PHASE_DISPLAY the root may be null, but we still want to get a hint of + // what the suggested launch display area would be. return RESULT_SKIP; } @@ -395,8 +397,9 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } private TaskDisplayArea getPreferredLaunchTaskDisplayArea(@Nullable Task task, - @Nullable ActivityOptions options, ActivityRecord source, LaunchParams currentParams, - @NonNull ActivityRecord activityRecord, @Nullable Request request) { + @Nullable ActivityOptions options, @Nullable ActivityRecord source, + @Nullable LaunchParams currentParams, @Nullable ActivityRecord activityRecord, + @Nullable Request request) { TaskDisplayArea taskDisplayArea = null; final WindowContainerToken optionLaunchTaskDisplayAreaToken = options != null @@ -438,8 +441,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { // If the source activity is a no-display activity, pass on the launch display area token // from source activity as currently preferred. - if (taskDisplayArea == null && source != null - && source.noDisplay) { + if (taskDisplayArea == null && source != null && source.noDisplay) { taskDisplayArea = source.mHandoverTaskDisplayArea; if (taskDisplayArea != null) { if (DEBUG) appendLog("display-area-from-no-display-source=" + taskDisplayArea); @@ -478,21 +480,24 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { } } - if (taskDisplayArea == null) { + if (taskDisplayArea == null && currentParams != null) { taskDisplayArea = currentParams.mPreferredTaskDisplayArea; + if (DEBUG) appendLog("display-area-from-current-params=" + taskDisplayArea); } // Re-route to default display if the device didn't declare support for multi-display if (taskDisplayArea != null && !mSupervisor.mService.mSupportsMultiDisplay && taskDisplayArea.getDisplayId() != DEFAULT_DISPLAY) { taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-area-from-no-multidisplay=" + taskDisplayArea); } // Re-route to default display if the home activity doesn't support multi-display - if (taskDisplayArea != null && activityRecord.isActivityTypeHome() + if (taskDisplayArea != null && activityRecord != null && activityRecord.isActivityTypeHome() && !mSupervisor.mRootWindowContainer.canStartHomeOnDisplayArea(activityRecord.info, taskDisplayArea, false /* allowInstrumenting */)) { taskDisplayArea = mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-area-from-home=" + taskDisplayArea); } return (taskDisplayArea != null) @@ -516,34 +521,56 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { * @return {@link TaskDisplayArea} to house the task */ private TaskDisplayArea getFallbackDisplayAreaForActivity( - @NonNull ActivityRecord activityRecord, @Nullable Request request) { - - WindowProcessController controllerFromLaunchingRecord = mSupervisor.mService - .getProcessController(activityRecord.launchedFromPid, - activityRecord.launchedFromUid); - final TaskDisplayArea displayAreaForLaunchingRecord = controllerFromLaunchingRecord == null - ? null : controllerFromLaunchingRecord.getTopActivityDisplayArea(); - if (displayAreaForLaunchingRecord != null) { - return displayAreaForLaunchingRecord; - } + @Nullable ActivityRecord activityRecord, @Nullable Request request) { + if (activityRecord != null) { + WindowProcessController controllerFromLaunchingRecord = + mSupervisor.mService.getProcessController( + activityRecord.launchedFromPid, activityRecord.launchedFromUid); + if (controllerFromLaunchingRecord != null) { + final TaskDisplayArea taskDisplayAreaForLaunchingRecord = + controllerFromLaunchingRecord.getTopActivityDisplayArea(); + if (taskDisplayAreaForLaunchingRecord != null) { + if (DEBUG) { + appendLog("display-area-for-launching-record=" + + taskDisplayAreaForLaunchingRecord); + } + return taskDisplayAreaForLaunchingRecord; + } + } - WindowProcessController controllerFromProcess = mSupervisor.mService.getProcessController( - activityRecord.getProcessName(), activityRecord.getUid()); - final TaskDisplayArea displayAreaForRecord = controllerFromProcess == null ? null - : controllerFromProcess.getTopActivityDisplayArea(); - if (displayAreaForRecord != null) { - return displayAreaForRecord; + WindowProcessController controllerFromProcess = + mSupervisor.mService.getProcessController( + activityRecord.getProcessName(), activityRecord.getUid()); + if (controllerFromProcess != null) { + final TaskDisplayArea displayAreaForRecord = + controllerFromProcess.getTopActivityDisplayArea(); + if (displayAreaForRecord != null) { + if (DEBUG) appendLog("display-area-for-record=" + displayAreaForRecord); + return displayAreaForRecord; + } + } } - WindowProcessController controllerFromRequest = request == null ? null : mSupervisor - .mService.getProcessController(request.realCallingPid, request.realCallingUid); - final TaskDisplayArea displayAreaFromSourceProcess = controllerFromRequest == null ? null - : controllerFromRequest.getTopActivityDisplayArea(); - if (displayAreaFromSourceProcess != null) { - return displayAreaFromSourceProcess; + if (request != null) { + WindowProcessController controllerFromRequest = + mSupervisor.mService.getProcessController( + request.realCallingPid, request.realCallingUid); + if (controllerFromRequest != null) { + final TaskDisplayArea displayAreaFromSourceProcess = + controllerFromRequest.getTopActivityDisplayArea(); + if (displayAreaFromSourceProcess != null) { + if (DEBUG) { + appendLog("display-area-source-process=" + displayAreaFromSourceProcess); + } + return displayAreaFromSourceProcess; + } + } } - return mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); + final TaskDisplayArea defaultTaskDisplayArea = + mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea(); + if (DEBUG) appendLog("display-area-from-default-fallback=" + defaultTaskDisplayArea); + return defaultTaskDisplayArea; } private boolean canInheritWindowingModeFromSource(@NonNull DisplayContent display, @@ -559,7 +586,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { return false; } - final int sourceWindowingMode = source.getWindowingMode(); + final int sourceWindowingMode = source.getTask().getWindowingMode(); if (sourceWindowingMode != WINDOWING_MODE_FULLSCREEN && sourceWindowingMode != WINDOWING_MODE_FREEFORM) { return false; diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index ceebb27642ce..bfe055354b9c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -911,6 +911,70 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } + private int runSetPersistentLetterboxPositionForHorizontalReachability(PrintWriter pw) + throws RemoteException { + @LetterboxHorizontalReachabilityPosition final int position; + try { + String arg = getNextArgRequired(); + switch (arg) { + case "left": + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT; + break; + case "center": + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER; + break; + case "right": + position = LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_RIGHT; + break; + default: + getErrPrintWriter().println( + "Error: 'left', 'center' or 'right' are expected as an argument"); + return -1; + } + } catch (IllegalArgumentException e) { + getErrPrintWriter().println( + "Error: 'left', 'center' or 'right' are expected as an argument" + e); + return -1; + } + synchronized (mInternal.mGlobalLock) { + mLetterboxConfiguration.setPersistentLetterboxPositionForHorizontalReachability( + false /* IsInBookMode */, position); + } + return 0; + } + + private int runSetPersistentLetterboxPositionForVerticalReachability(PrintWriter pw) + throws RemoteException { + @LetterboxVerticalReachabilityPosition final int position; + try { + String arg = getNextArgRequired(); + switch (arg) { + case "top": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP; + break; + case "center": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER; + break; + case "bottom": + position = LETTERBOX_VERTICAL_REACHABILITY_POSITION_BOTTOM; + break; + default: + getErrPrintWriter().println( + "Error: 'top', 'center' or 'bottom' are expected as an argument"); + return -1; + } + } catch (IllegalArgumentException e) { + getErrPrintWriter().println( + "Error: 'top', 'center' or 'bottom' are expected as an argument" + e); + return -1; + } + synchronized (mInternal.mGlobalLock) { + mLetterboxConfiguration.setPersistentLetterboxPositionForVerticalReachability( + false /* forTabletopMode */, position); + } + return 0; + } + private int runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter) throws RemoteException { String arg = getNextArg(); @@ -994,6 +1058,12 @@ public class WindowManagerShellCommand extends ShellCommand { case "--defaultPositionForVerticalReachability": runSetLetterboxDefaultPositionForVerticalReachability(pw); break; + case "--persistentPositionForHorizontalReachability": + runSetPersistentLetterboxPositionForHorizontalReachability(pw); + break; + case "--persistentPositionForVerticalReachability": + runSetPersistentLetterboxPositionForVerticalReachability(pw); + break; case "--isEducationEnabled": runSetBooleanFlag(pw, mLetterboxConfiguration::setIsEducationEnabled); break; @@ -1080,6 +1150,14 @@ public class WindowManagerShellCommand extends ShellCommand { case "defaultPositionForVerticalReachability": mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); break; + case "persistentPositionForHorizontalReachability": + mLetterboxConfiguration + .resetPersistentLetterboxPositionForHorizontalReachability(); + break; + case "persistentPositionForVerticalReachability": + mLetterboxConfiguration + .resetPersistentLetterboxPositionForVerticalReachability(); + break; case "isEducationEnabled": mLetterboxConfiguration.resetIsEducationEnabled(); break; @@ -1206,6 +1284,8 @@ public class WindowManagerShellCommand extends ShellCommand { mLetterboxConfiguration.resetEnabledAutomaticReachabilityInBookMode(); mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability(); mLetterboxConfiguration.resetDefaultPositionForVerticalReachability(); + mLetterboxConfiguration.resetPersistentLetterboxPositionForHorizontalReachability(); + mLetterboxConfiguration.resetPersistentLetterboxPositionForVerticalReachability(); mLetterboxConfiguration.resetIsEducationEnabled(); mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled(); mLetterboxConfiguration.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox(); @@ -1233,6 +1313,12 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println("Vertical position multiplier (tabletop mode): " + mLetterboxConfiguration.getLetterboxVerticalPositionMultiplier( true /* isInTabletopMode */)); + pw.println("Horizontal position multiplier for reachability: " + + mLetterboxConfiguration.getHorizontalMultiplierForReachability( + false /* isInBookMode */)); + pw.println("Vertical position multiplier for reachability: " + + mLetterboxConfiguration.getVerticalMultiplierForReachability( + false /* isInTabletopMode */)); pw.println("Aspect ratio: " + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio()); pw.println("Default min aspect ratio for unresizable apps: " @@ -1472,6 +1558,12 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println(" --defaultPositionForVerticalReachability [top|center|bottom]"); pw.println(" Default position of app window when vertical reachability is."); pw.println(" enabled."); + pw.println(" --persistentPositionForHorizontalReachability [left|center|right]"); + pw.println(" Persistent position of app window when horizontal reachability is."); + pw.println(" enabled."); + pw.println(" --persistentPositionForVerticalReachability [top|center|bottom]"); + pw.println(" Persistent position of app window when vertical reachability is."); + pw.println(" enabled."); pw.println(" --isEducationEnabled [true|1|false|0]"); pw.println(" Whether education is allowed for letterboxed fullscreen apps."); pw.println(" --isSplitScreenAspectRatioForUnresizableAppsEnabled [true|1|false|0]"); @@ -1493,8 +1585,10 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha"); pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier"); pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled"); - pw.println(" |isEducationEnabled||defaultPositionMultiplierForHorizontalReachability"); + pw.println(" |isEducationEnabled|defaultPositionMultiplierForHorizontalReachability"); pw.println(" |isTranslucentLetterboxingEnabled|isUserAppAspectRatioSettingsEnabled"); + pw.println(" |persistentPositionMultiplierForHorizontalReachability"); + pw.println(" |persistentPositionMultiplierForVerticalReachability"); pw.println(" |defaultPositionMultiplierForVerticalReachability]"); pw.println(" Resets overrides to default values for specified properties separated"); pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'."); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index a172d9912cbd..9c04e0aab8f3 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1759,7 +1759,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP bounds.set(mWindowFrames.mFrame); bounds.inset(getInsetsStateWithVisibilityOverride().calculateVisibleInsets( - bounds, mAttrs.type, getWindowingMode(), mAttrs.softInputMode, mAttrs.flags)); + bounds, mAttrs.type, getActivityType(), mAttrs.softInputMode, mAttrs.flags)); if (intersectWithRootTaskBounds) { bounds.intersect(mTmpRect); } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 2a995b24ef4f..ec5378f01ce3 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -41,6 +41,7 @@ cc_library_static { "com_android_server_companion_virtual_InputController.cpp", "com_android_server_devicepolicy_CryptoTestHelper.cpp", "com_android_server_display_DisplayControl.cpp", + "com_android_server_display_SmallAreaDetectionController.cpp", "com_android_server_connectivity_Vpn.cpp", "com_android_server_gpu_GpuService.cpp", "com_android_server_HardwarePropertiesManagerService.cpp", diff --git a/services/core/jni/com_android_server_display_SmallAreaDetectionController.cpp b/services/core/jni/com_android_server_display_SmallAreaDetectionController.cpp new file mode 100644 index 000000000000..b256f168f2af --- /dev/null +++ b/services/core/jni/com_android_server_display_SmallAreaDetectionController.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SmallAreaDetectionController" + +#include <gui/SurfaceComposerClient.h> +#include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedPrimitiveArray.h> + +#include "jni.h" +#include "utils/Log.h" + +namespace android { +static void nativeUpdateSmallAreaDetection(JNIEnv* env, jclass clazz, jintArray juids, + jfloatArray jthresholds) { + if (juids == nullptr || jthresholds == nullptr) return; + + ScopedIntArrayRO uids(env, juids); + ScopedFloatArrayRO thresholds(env, jthresholds); + + if (uids.size() != thresholds.size()) { + ALOGE("uids size exceeds thresholds size!"); + return; + } + + std::vector<int32_t> uidVector; + std::vector<float> thresholdVector; + size_t size = uids.size(); + uidVector.reserve(size); + thresholdVector.reserve(size); + for (int i = 0; i < size; i++) { + uidVector.push_back(static_cast<int32_t>(uids[i])); + thresholdVector.push_back(static_cast<float>(thresholds[i])); + } + SurfaceComposerClient::updateSmallAreaDetection(uidVector, thresholdVector); +} + +static void nativeSetSmallAreaDetectionThreshold(JNIEnv* env, jclass clazz, jint uid, + jfloat threshold) { + SurfaceComposerClient::setSmallAreaDetectionThreshold(uid, threshold); +} + +static const JNINativeMethod gMethods[] = { + {"nativeUpdateSmallAreaDetection", "([I[F)V", (void*)nativeUpdateSmallAreaDetection}, + {"nativeSetSmallAreaDetectionThreshold", "(IF)V", + (void*)nativeSetSmallAreaDetectionThreshold}, +}; + +int register_android_server_display_smallAreaDetectionController(JNIEnv* env) { + return jniRegisterNativeMethods(env, "com/android/server/display/SmallAreaDetectionController", + gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 97d7be6a718e..f6f673746609 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -67,6 +67,7 @@ int register_android_server_app_GameManagerService(JNIEnv* env); int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env); int register_com_android_server_display_DisplayControl(JNIEnv* env); int register_com_android_server_SystemClockTime(JNIEnv* env); +int register_android_server_display_smallAreaDetectionController(JNIEnv* env); }; using namespace android; @@ -126,5 +127,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_com_android_server_wm_TaskFpsCallbackController(env); register_com_android_server_display_DisplayControl(env); register_com_android_server_SystemClockTime(env); + register_android_server_display_smallAreaDetectionController(env); return JNI_VERSION_1_4; } diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index d833fbd6ffd2..d22e02e9dae6 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -67,6 +67,18 @@ <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowIncrease"> <xs:annotation name="final"/> </xs:element> + <!-- Ramp speed used to decrease the screen brightness when in idle mode. + In framework brightness units per second. Must exist with + screenBrightnessRampSlowIncreaseIdle--> + <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowDecreaseIdle"> + <xs:annotation name="final"/> + </xs:element> + <!-- Ramp speed used to decrease the screen brightness when in idle mode. + In framework brightness units per second. Must exist with + screenBrightnessRampSlowDecreaseIdle--> + <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowIncreaseIdle"> + <xs:annotation name="final"/> + </xs:element> <!-- Maximum time in milliseconds that a brightness increase animation can take. --> <xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampIncreaseMaxMillis"> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index d2ac1aae1500..6364c1feb659 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -115,7 +115,9 @@ package com.android.server.display.config { method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease(); method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis(); method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease(); + method public final java.math.BigDecimal getScreenBrightnessRampSlowDecreaseIdle(); method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease(); + method public final java.math.BigDecimal getScreenBrightnessRampSlowIncreaseIdle(); method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor(); method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux(); method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling(); @@ -142,7 +144,9 @@ package com.android.server.display.config { method public final void setScreenBrightnessRampFastIncrease(java.math.BigDecimal); method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger); method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal); + method public final void setScreenBrightnessRampSlowDecreaseIdle(java.math.BigDecimal); method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal); + method public final void setScreenBrightnessRampSlowIncreaseIdle(java.math.BigDecimal); method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails); method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray); method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index af1bac890ff1..438a9d6753b6 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -680,7 +680,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // to decide whether an existing policy in the {@link #DEVICE_POLICIES_XML} needs to // be upgraded. See {@link PolicyVersionUpgrader} on instructions how to add an upgrade // step. - static final int DPMS_VERSION = 5; + static final int DPMS_VERSION = 6; static { SECURE_SETTINGS_ALLOWLIST = new ArraySet<>(); @@ -876,8 +876,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG = true; // TODO(b/265683382) remove the flag after rollout. - private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running"; - public static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = true; + public static final boolean DEFAULT_KEEP_PROFILES_RUNNING_FLAG = false; // TODO(b/261999445) remove the flag after rollout. private static final String HEADLESS_FLAG = "headless"; @@ -2594,6 +2593,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true, userHandle); } + // Enforcing the restriction of private profile creation in case device owner is set. + if (!mUserManager.hasUserRestriction( + UserManager.DISALLOW_ADD_PRIVATE_PROFILE, userHandle)) { + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, true, + userHandle); + } // Creation of managed profile is restricted in case device owner is set, enforcing this // restriction by setting user level restriction at time of device owner setup. if (!mUserManager.hasUserRestriction( @@ -4036,6 +4041,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, false, user); } + + // When a device owner is set, the system automatically restricts adding a + // private profile. + // Remove this restriction when the device owner is cleared. + if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + user)) { + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + false, user); + } } } else { // ManagedProvisioning/DPC sets DISALLOW_ADD_USER. Clear to recover to the original state @@ -4061,6 +4075,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { false, userHandle); } + + // When a device owner is set, the system automatically restricts adding a + // private profile. + // Remove this restriction when the device owner is cleared. + if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + userHandle)) { + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + false, userHandle); + } } } @@ -9423,6 +9446,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true, UserHandle.of(u)); + + // Restrict adding a private profile when a device owner is set. + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + true, + UserHandle.of(u)); } } else { mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, @@ -9435,6 +9463,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true, UserHandle.of(userId)); + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + true, + UserHandle.of(userId)); } // TODO Send to system too? sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId); @@ -13200,6 +13231,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { USER_RESTRICTION_PERMISSIONS.put( UserManager.DISALLOW_ADD_CLONE_PROFILE, new String[]{MANAGE_DEVICE_POLICY_PROFILES}); USER_RESTRICTION_PERMISSIONS.put( + UserManager.DISALLOW_ADD_PRIVATE_PROFILE, new String[]{MANAGE_DEVICE_POLICY_PROFILES}); + USER_RESTRICTION_PERMISSIONS.put( UserManager.DISALLOW_ADD_USER, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS}); USER_RESTRICTION_PERMISSIONS.put( UserManager.DISALLOW_ADD_WIFI_CONFIG, new String[]{MANAGE_DEVICE_POLICY_WIFI}); @@ -22977,10 +23010,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private static boolean isKeepProfilesRunningFlagEnabled() { - return DeviceConfig.getBoolean( - NAMESPACE_DEVICE_POLICY_MANAGER, - KEEP_PROFILES_RUNNING_FLAG, - DEFAULT_KEEP_PROFILES_RUNNING_FLAG); + return DEFAULT_KEEP_PROFILES_RUNNING_FLAG; } private boolean isUnicornFlagEnabled() { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index 7a877b9afdad..0fc8c5e7a46a 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -426,6 +426,7 @@ final class PolicyDefinition<V> { USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_USER, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_MANAGED_PROFILE, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_CLONE_PROFILE, /* flags= */ 0); + USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.ENSURE_VERIFY_APPS, POLICY_FLAG_GLOBAL_ONLY_POLICY); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, /* flags= */ 0); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java index 733b1d98f3e2..f060426ec827 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyVersionUpgrader.java @@ -117,6 +117,19 @@ public class PolicyVersionUpgrader { currentVersion = 5; } + if (currentVersion == 5) { + Slog.i(LOG_TAG, String.format("Upgrading from version %d", currentVersion)); + // No-op upgrade here: + // DevicePolicyData.mEffectiveKeepProfilesRunning is only stored in XML file when it is + // different from its default value, otherwise the tag is not written. When loading, if + // the tag is missing, the field retains the value previously assigned in the + // constructor, which is the default value. + // In version 5 the default value was 'true', in version 6 it is 'false', so when + // loading XML version 5 we need to initialize the field to 'true' for it to be restored + // correctly in case the tag is missing. This is done in loadDataForUser(). + currentVersion = 6; + } + writePoliciesAndVersion(allUsers, allUsersData, ownersData, currentVersion); } @@ -282,6 +295,10 @@ public class PolicyVersionUpgrader { private DevicePolicyData loadDataForUser( int userId, int loadVersion, ComponentName ownerComponent) { DevicePolicyData policy = new DevicePolicyData(userId); + // See version 5 -> 6 step in upgradePolicy() + if (loadVersion == 5 && userId == UserHandle.USER_SYSTEM) { + policy.mEffectiveKeepProfilesRunning = true; + } DevicePolicyData.load(policy, mProvider.makeDevicePoliciesJournaledFile(userId), mProvider.getAdminInfoSupplier(userId), diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java index 98c6c424e223..e2939c1aff3b 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java @@ -612,9 +612,6 @@ public class ScanTests { final PackageSetting pkgSetting = scanResult.mPkgSetting; assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting); - // pretend that the data dir has been set up already, so that the generated applicationInfo - // includes the expected data dir string - pkgSetting.setCeDataInode(/* ceDataInode= */100, /* userId= */0); final ApplicationInfo applicationInfo = PackageInfoUtils.generateApplicationInfo( pkgSetting.getPkg(), 0, pkgSetting.getUserStateOrDefault(0), 0, pkgSetting); diff --git a/services/tests/displayservicetests/Android.bp b/services/tests/displayservicetests/Android.bp index fb14419a13c0..e28028f9fc2b 100644 --- a/services/tests/displayservicetests/Android.bp +++ b/services/tests/displayservicetests/Android.bp @@ -35,6 +35,7 @@ android_test { "mockingservicestests-utils-mockito", "platform-compat-test-rules", "platform-test-annotations", + "service-permission.stubs.system_server", "services.core", "servicestests-utils", "testables", diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java index d099693ffc82..a23539e37409 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -28,6 +28,7 @@ import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK; import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -53,6 +54,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.PropertyInvalidatedCache; import android.companion.virtual.IVirtualDevice; import android.companion.virtual.IVirtualDeviceManager; @@ -61,6 +64,7 @@ import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageManager; +import android.content.pm.PackageManagerInternal; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; @@ -110,6 +114,7 @@ import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.input.InputManagerInternal; import com.android.server.lights.LightsManager; +import com.android.server.pm.UserManagerInternal; import com.android.server.sensors.SensorManagerInternal; import com.android.server.wm.WindowManagerInternal; @@ -288,10 +293,11 @@ public class DisplayManagerServiceTest { @Mock LocalDisplayAdapter.SurfaceControlProxy mSurfaceControlProxy; @Mock IBinder mMockDisplayToken; @Mock SensorManagerInternal mMockSensorManagerInternal; - @Mock SensorManager mSensorManager; - @Mock DisplayDeviceConfig mMockDisplayDeviceConfig; + @Mock PackageManagerInternal mMockPackageManagerInternal; + @Mock UserManagerInternal mMockUserManagerInternal; + @Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor; @Mock DisplayManagerFlags mMockFlags; @@ -312,6 +318,10 @@ public class DisplayManagerServiceTest { LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class); LocalServices.addService( VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal); + LocalServices.removeServiceForTest(PackageManagerInternal.class); + LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal); + LocalServices.removeServiceForTest(UserManagerInternal.class); + LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal); // TODO: b/287945043 mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); mResources = Mockito.spy(mContext.getResources()); @@ -627,7 +637,7 @@ public class DisplayManagerServiceTest { * Tests that the virtual display is created along-side the default display. */ @Test - public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { + public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); registerDefaultDisplays(displayManager); @@ -663,7 +673,7 @@ public class DisplayManagerServiceTest { * internal state for things like display cutout when nonOverrideDisplayInfo is changed. */ @Test - public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() throws Exception { + public void testShouldNotifyChangeWhenNonOverrideDisplayInfoChanged() { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); registerDefaultDisplays(displayManager); @@ -1486,7 +1496,7 @@ public class DisplayManagerServiceTest { * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted. */ @Test - public void testOwnDisplayGroup_allowCreationWithVirtualDevice() throws Exception { + public void testOwnDisplayGroup_allowCreationWithVirtualDevice() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); DisplayManagerInternal localService = displayManager.new LocalService(); @@ -1650,7 +1660,7 @@ public class DisplayManagerServiceTest { */ @Test @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) - public void testDisplayInfoFrameRateOverrideModeCompat() throws Exception { + public void testDisplayInfoFrameRateOverrideModeCompat() { testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ false); } @@ -1659,7 +1669,7 @@ public class DisplayManagerServiceTest { */ @Test @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) - public void testDisplayInfoFrameRateOverrideMode() throws Exception { + public void testDisplayInfoFrameRateOverrideMode() { testDisplayInfoFrameRateOverrideModeCompat(/*compatChangeEnabled*/ true); } @@ -1742,7 +1752,7 @@ public class DisplayManagerServiceTest { */ @Test @DisableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) - public void testDisplayInfoRenderFrameRateModeCompat() throws Exception { + public void testDisplayInfoRenderFrameRateModeCompat() { testDisplayInfoRenderFrameRateModeCompat(/*compatChangeEnabled*/ false); } @@ -1751,7 +1761,7 @@ public class DisplayManagerServiceTest { */ @Test @EnableCompatChanges({DisplayManagerService.DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE}) - public void testDisplayInfoRenderFrameRateMode() throws Exception { + public void testDisplayInfoRenderFrameRateMode() { testDisplayInfoRenderFrameRateModeCompat(/*compatChangeEnabled*/ true); } @@ -2104,10 +2114,11 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); @@ -2124,16 +2135,19 @@ public class DisplayManagerServiceTest { DisplayManagerInternal localService = displayManager.new LocalService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); - // Create default display device - createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); - bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); localService.registerDisplayGroupListener(callback); + callback.expectsEvent(EVENT_DISPLAY_ADDED); + // Create default display device + createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); + callback.waitForExpectedEvent(); + callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_CONNECTED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); @@ -2151,8 +2165,9 @@ public class DisplayManagerServiceTest { FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_CONNECTED, EVENT_DISPLAY_ADDED).inOrder(); @@ -2166,18 +2181,22 @@ public class DisplayManagerServiceTest { DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); + bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); // Create default display device createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); - bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.waitForExpectedEvent(); + callback.expectsEvent(EVENT_DISPLAY_CONNECTED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_ADDED); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); displayManager.enableConnectedDisplay(display.getDisplayIdLocked(), /* enabled= */ true); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(display.isEnabledLocked()).isTrue(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_ADDED).inOrder(); @@ -2190,11 +2209,15 @@ public class DisplayManagerServiceTest { DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); + bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); // Create default display device createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); + callback.waitForExpectedEvent(); bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); + // Withouts permission, we cannot get the CONNECTED event. waitForIdleHandler(displayManager.getDisplayHandler()); callback.clear(); LogicalDisplay display = @@ -2212,19 +2235,22 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); + callback.expectsEvent(EVENT_DISPLAY_REMOVED); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ false); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_ADDED); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ true); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_ADDED); } @@ -2237,16 +2263,18 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); + callback.expectsEvent(EVENT_DISPLAY_REMOVED); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ false); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_REMOVED); } @@ -2259,23 +2287,26 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); DisplayManagerInternal localService = displayManager.new LocalService(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); - // Create default display device - createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); localService.registerDisplayGroupListener(callback); + callback.expectsEvent(EVENT_DISPLAY_ADDED); + // Create default display device + createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); + callback.waitForExpectedEvent(); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); + callback.expectsEvent(EVENT_DISPLAY_ADDED); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ true); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_REMOVED); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ false); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(display.isEnabledLocked()).isFalse(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_REMOVED); @@ -2288,18 +2319,20 @@ public class DisplayManagerServiceTest { DisplayManagerService.BinderService bs = displayManager.new BinderService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); + bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); // Create default display device createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); - bs.registerCallbackWithEventMask(callback, STANDARD_DISPLAY_EVENTS); + callback.waitForExpectedEvent(); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.expectsEvent(EVENT_DISPLAY_ADDED); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); int displayId = display.getDisplayIdLocked(); logicalDisplayMapper.setEnabledLocked(display, /* isEnabled= */ true); logicalDisplayMapper.updateLogicalDisplays(); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); assertThrows(SecurityException.class, () -> bs.disableConnectedDisplay(displayId)); @@ -2314,23 +2347,27 @@ public class DisplayManagerServiceTest { DisplayManagerInternal localService = displayManager.new LocalService(); LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); - // Create default display device - createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); localService.registerDisplayGroupListener(callback); + callback.expectsEvent(EVENT_DISPLAY_ADDED); + // Create default display device' + createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); + callback.waitForExpectedEvent(); + callback.expectsEvent(EVENT_DISPLAY_CONNECTED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice); int groupId = display.getDisplayInfoLocked().displayGroupId; DisplayGroup group = logicalDisplayMapper.getDisplayGroupLocked(groupId); assertThat(group.getSizeLocked()).isEqualTo(1); + callback.expectsEvent(DISPLAY_GROUP_EVENT_REMOVED); display.setPrimaryDisplayDeviceLocked(null); displayManager.getDisplayDeviceRepository() .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(group.getSizeLocked()).isEqualTo(0); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_DISCONNECTED, @@ -2357,20 +2394,23 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_CONNECTED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_EXTERNAL); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); + callback.expectsEvent(EVENT_DISPLAY_ADDED); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); int displayId = display.getDisplayIdLocked(); displayManager.enableConnectedDisplay(displayId, /* enabled= */ true); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_DISCONNECTED); display.setPrimaryDisplayDeviceLocked(null); displayManager.getDisplayDeviceRepository() .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(logicalDisplayMapper.getDisplayLocked(displayId, true)).isNull(); assertThat(callback.receivedEvents()).containsExactly(EVENT_DISPLAY_REMOVED, @@ -2386,17 +2426,19 @@ public class DisplayManagerServiceTest { LogicalDisplayMapper logicalDisplayMapper = displayManager.getLogicalDisplayMapper(); FakeDisplayManagerCallback callback = new FakeDisplayManagerCallback(); bs.registerCallbackWithEventMask(callback, STANDARD_AND_CONNECTION_DISPLAY_EVENTS); + callback.expectsEvent(EVENT_DISPLAY_ADDED); FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f}, Display.TYPE_INTERNAL); LogicalDisplay display = logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); callback.clear(); + callback.expectsEvent(EVENT_DISPLAY_DISCONNECTED); display.setPrimaryDisplayDeviceLocked(null); displayManager.getDisplayDeviceRepository() .onDisplayDeviceEvent(displayDevice, DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); - waitForIdleHandler(displayManager.getDisplayHandler()); + callback.waitForExpectedEvent(); assertThat(logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true)).isNull(); @@ -2675,6 +2717,12 @@ public class DisplayManagerServiceTest { int mDisplayId; List<String> mReceivedEvents = new ArrayList<>(); + @Nullable + private String mExpectedEvent; + + @NonNull + private volatile CountDownLatch mLatch = new CountDownLatch(0); + FakeDisplayManagerCallback(int displayId) { mDisplayId = displayId; } @@ -2683,6 +2731,30 @@ public class DisplayManagerServiceTest { mDisplayId = -1; } + void expectsEvent(@NonNull String event) { + mExpectedEvent = event; + mLatch = new CountDownLatch(1); + } + + void waitForExpectedEvent() { + waitForExpectedEvent(Duration.ofSeconds(1)); + } + + void waitForExpectedEvent(Duration timeout) { + try { + assertWithMessage("Event '" + mExpectedEvent + "' is received.") + .that(mLatch.await(timeout.toMillis(), TimeUnit.MILLISECONDS)).isTrue(); + } catch (InterruptedException ex) { + throw new AssertionError("Waiting for expected event interrupted", ex); + } + } + + private void eventSeen(String event) { + if (event.equals(mExpectedEvent)) { + mLatch.countDown(); + } + } + @Override public void onDisplayEvent(int displayId, int event) { if (mDisplayId != -1 && displayId != mDisplayId) { @@ -2693,22 +2765,27 @@ public class DisplayManagerServiceTest { // 1 - The error produced is a lot easier to read // 2 - The values used for display and group events are the same, strings are used to // differentiate them easily. - mReceivedEvents.add(eventTypeToString(event)); + String eventName = eventTypeToString(event); + mReceivedEvents.add(eventName); + eventSeen(eventName); } @Override public void onDisplayGroupAdded(int groupId) { mReceivedEvents.add(DISPLAY_GROUP_EVENT_ADDED); + eventSeen(DISPLAY_GROUP_EVENT_ADDED); } @Override public void onDisplayGroupRemoved(int groupId) { mReceivedEvents.add(DISPLAY_GROUP_EVENT_REMOVED); + eventSeen(DISPLAY_GROUP_EVENT_REMOVED); } @Override public void onDisplayGroupChanged(int groupId) { mReceivedEvents.add(DISPLAY_GROUP_EVENT_CHANGED); + eventSeen(DISPLAY_GROUP_EVENT_CHANGED); } public void clear() { diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java index 4cbdd09319cc..e7dc48e529eb 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java @@ -101,6 +101,8 @@ public final class DisplayPowerController2Test { private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f; + private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f; + private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f; private OffsettableClock mClock; private TestLooper mTestLooper; @@ -1116,6 +1118,63 @@ public final class DisplayPowerController2Test { verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true); } + @Test + public void testRampRatesIdle() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + float brightness = 0.6f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); + brightness = 0.05f; + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + // The second time, the animation rate should be slow + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE)); + + brightness = 0.9f; + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + // The third time, the animation rate should be slow + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE)); + } + + @Test + public void testPowerStateStopsOnDpcStop() { + // Set up + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); + + // Stop dpc + mHolder.dpc.stop(); + advanceTime(1); + + // Ensure dps has stopped + verify(mHolder.displayPowerState, times(1)).stop(); + } + /** * Creates a mock and registers it to {@link LocalServices}. */ @@ -1187,6 +1246,10 @@ public final class DisplayPowerController2Test { .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE); when(displayDeviceConfigMock.getBrightnessRampSlowIncrease()) .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE); + when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle()) + .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE); + when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle()) + .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE); } private DisplayPowerControllerHolder createDisplayPowerController(int displayId, diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java index 68bbcbc1df51..2640390ceecf 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java @@ -101,6 +101,8 @@ public final class DisplayPowerControllerTest { private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f; private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f; + private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f; + private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f; private OffsettableClock mClock; private TestLooper mTestLooper; @@ -1123,6 +1125,63 @@ public final class DisplayPowerControllerTest { verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true); } + @Test + public void testRampRatesIdle() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + float brightness = 0.6f; + when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON); + when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f); + when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true); + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); // Run updatePowerState + + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE)); + + when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness); + brightness = 0.05f; + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + + // The second time, the animation rate should be slow + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE)); + + brightness = 0.9f; + when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness( + any(BrightnessEvent.class))).thenReturn(brightness); + + mHolder.dpc.updateBrightness(); + advanceTime(1); // Run updatePowerState + // The third time, the animation rate should be slow + verify(mHolder.animator).animateTo(eq(brightness), anyFloat(), + eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE)); + } + + @Test + public void testPowerStateStopsOnDpcStop() { + // Set up + DisplayPowerRequest dpr = new DisplayPowerRequest(); + mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false); + advanceTime(1); + + // Stop dpc + mHolder.dpc.stop(); + advanceTime(1); + + // Ensure dps has stopped + verify(mHolder.displayPowerState, times(1)).stop(); + } + private void advanceTime(long timeMs) { mClock.fastForward(timeMs); mTestLooper.dispatchAll(); @@ -1186,6 +1245,10 @@ public final class DisplayPowerControllerTest { .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE); when(displayDeviceConfigMock.getBrightnessRampSlowIncrease()) .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE); + when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle()) + .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE); + when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle()) + .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE); } private DisplayPowerControllerHolder createDisplayPowerController(int displayId, diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java new file mode 100644 index 000000000000..167a412d3860 --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerStateTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; + +import static org.mockito.Mockito.times; + +import android.os.Handler; +import android.os.test.TestLooper; +import android.view.Display; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + + +@SmallTest +public class DisplayPowerStateTest { + private static final int DISPLAY_ID = 123; + + private DisplayPowerState mDisplayPowerState; + private TestLooper mTestLooper; + @Mock + private DisplayBlanker mDisplayBlankerMock; + @Mock + private ColorFade mColorFadeMock; + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Before + public void setUp() { + mTestLooper = new TestLooper(); + mDisplayPowerState = new DisplayPowerState( + mDisplayBlankerMock, mColorFadeMock, DISPLAY_ID, Display.STATE_ON, + new Handler(mTestLooper.getLooper())); + } + + @Test + public void testColorFadeStopsOnDpsStop() { + mDisplayPowerState.stop(); + verify(mColorFadeMock, times(1)).stop(); + } +} diff --git a/services/tests/mockingservicestests/src/com/android/server/display/SmallAreaDetectionControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/SmallAreaDetectionControllerTest.java new file mode 100644 index 000000000000..1ce79a5b596b --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/display/SmallAreaDetectionControllerTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import static android.os.Process.INVALID_UID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ContextWrapper; +import android.content.pm.PackageManagerInternal; +import android.provider.DeviceConfigInterface; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.server.LocalServices; +import com.android.server.pm.UserManagerInternal; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class SmallAreaDetectionControllerTest { + + @Rule + public MockitoRule mRule = MockitoJUnit.rule(); + + @Mock + private PackageManagerInternal mMockPackageManagerInternal; + @Mock + private UserManagerInternal mMockUserManagerInternal; + + private SmallAreaDetectionController mSmallAreaDetectionController; + + private static final String PKG_A = "com.a.b.c"; + private static final String PKG_B = "com.d.e.f"; + private static final String PKG_NOT_INSTALLED = "com.not.installed"; + private static final float THRESHOLD_A = 0.05f; + private static final float THRESHOLD_B = 0.07f; + private static final int USER_1 = 110; + private static final int USER_2 = 111; + private static final int UID_A_1 = 11011111; + private static final int UID_A_2 = 11111111; + private static final int UID_B_1 = 11022222; + private static final int UID_B_2 = 11122222; + + @Before + public void setup() { + LocalServices.removeServiceForTest(PackageManagerInternal.class); + LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal); + LocalServices.removeServiceForTest(UserManagerInternal.class); + LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal); + + when(mMockUserManagerInternal.getUserIds()).thenReturn(new int[]{USER_1, USER_2}); + when(mMockPackageManagerInternal.getPackageUid(PKG_A, 0, USER_1)).thenReturn(UID_A_1); + when(mMockPackageManagerInternal.getPackageUid(PKG_A, 0, USER_2)).thenReturn(UID_A_2); + when(mMockPackageManagerInternal.getPackageUid(PKG_B, 0, USER_1)).thenReturn(UID_B_1); + when(mMockPackageManagerInternal.getPackageUid(PKG_B, 0, USER_2)).thenReturn(UID_B_2); + when(mMockPackageManagerInternal.getPackageUid(PKG_NOT_INSTALLED, 0, USER_1)).thenReturn( + INVALID_UID); + when(mMockPackageManagerInternal.getPackageUid(PKG_NOT_INSTALLED, 0, USER_2)).thenReturn( + INVALID_UID); + + mSmallAreaDetectionController = spy(new SmallAreaDetectionController( + new ContextWrapper(ApplicationProvider.getApplicationContext()), + DeviceConfigInterface.REAL)); + doNothing().when(mSmallAreaDetectionController).updateSmallAreaDetection(any(), any()); + } + + @Test + public void testUpdateAllowlist_validProperty() { + final String property = PKG_A + ":" + THRESHOLD_A + "," + PKG_B + ":" + THRESHOLD_B; + mSmallAreaDetectionController.updateAllowlist(property); + + final int[] resultUidArray = {UID_A_1, UID_B_1, UID_A_2, UID_B_2}; + final float[] resultThresholdArray = {THRESHOLD_A, THRESHOLD_B, THRESHOLD_A, THRESHOLD_B}; + verify(mSmallAreaDetectionController).updateSmallAreaDetection(eq(resultUidArray), + eq(resultThresholdArray)); + } + + @Test + public void testUpdateAllowlist_includeInvalidRow() { + final String property = PKG_A + "," + PKG_B + ":" + THRESHOLD_B; + mSmallAreaDetectionController.updateAllowlist(property); + + final int[] resultUidArray = {UID_B_1, UID_B_2}; + final float[] resultThresholdArray = {THRESHOLD_B, THRESHOLD_B}; + verify(mSmallAreaDetectionController).updateSmallAreaDetection(eq(resultUidArray), + eq(resultThresholdArray)); + } + + @Test + public void testUpdateAllowlist_includeNotInstalledPkg() { + final String property = + PKG_A + ":" + THRESHOLD_A + "," + PKG_NOT_INSTALLED + ":" + THRESHOLD_B; + mSmallAreaDetectionController.updateAllowlist(property); + + final int[] resultUidArray = {UID_A_1, UID_A_2}; + final float[] resultThresholdArray = {THRESHOLD_A, THRESHOLD_A}; + verify(mSmallAreaDetectionController).updateSmallAreaDetection(eq(resultUidArray), + eq(resultThresholdArray)); + } + + @Test + public void testUpdateAllowlist_invalidProperty() { + final String property = PKG_A; + mSmallAreaDetectionController.updateAllowlist(property); + + verify(mSmallAreaDetectionController, never()).updateSmallAreaDetection(any(), any()); + } +} diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java index c7e1bda2e1b8..e58a2342a718 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java @@ -16,41 +16,51 @@ package com.android.server.pm; +import static android.content.Intent.FLAG_RECEIVER_FOREGROUND; import static android.content.pm.PackageManager.DELETE_KEEP_DATA; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AppOpsManager; import android.content.Context; +import android.content.Intent; import android.content.IntentSender; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; +import android.content.pm.PackageArchiver; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.os.Binder; import android.os.Build; +import android.os.Bundle; import android.os.ParcelableException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; +import android.text.TextUtils; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.pm.pkg.ArchiveState; import com.android.server.pm.pkg.PackageStateInternal; +import com.android.server.pm.pkg.PackageUserStateImpl; 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.MockitoAnnotations; @@ -64,7 +74,8 @@ import java.util.List; public class PackageArchiverServiceTest { private static final String PACKAGE = "com.example"; - private static final String CALLER_PACKAGE = "com.vending"; + private static final String CALLER_PACKAGE = "com.caller"; + private static final String INSTALLER_PACKAGE = "com.installer"; @Rule public final MockSystemRule mMockSystem = new MockSystemRule(); @@ -84,11 +95,11 @@ public class PackageArchiverServiceTest { private final InstallSource mInstallSource = InstallSource.create( - CALLER_PACKAGE, - CALLER_PACKAGE, - CALLER_PACKAGE, + INSTALLER_PACKAGE, + INSTALLER_PACKAGE, + INSTALLER_PACKAGE, Binder.getCallingUid(), - CALLER_PACKAGE, + INSTALLER_PACKAGE, /* installerAttributionTag= */ null, /* packageSource= */ 0); @@ -96,6 +107,8 @@ public class PackageArchiverServiceTest { private final int mUserId = UserHandle.CURRENT.getIdentifier(); + private PackageUserStateImpl mUserState; + private PackageSetting mPackageSetting; private PackageArchiverService mArchiveService; @@ -116,11 +129,16 @@ public class PackageArchiverServiceTest { when(mComputer.getPackageStateFiltered(eq(PACKAGE), anyInt(), anyInt())).thenReturn( mPackageState); + when(mComputer.getPackageStateFiltered(eq(INSTALLER_PACKAGE), anyInt(), + anyInt())).thenReturn(mock(PackageStateInternal.class)); when(mPackageState.getPackageName()).thenReturn(PACKAGE); when(mPackageState.getInstallSource()).thenReturn(mInstallSource); mPackageSetting = createBasicPackageSetting(); when(mMockSystem.mocks().getSettings().getPackageLPr(eq(PACKAGE))).thenReturn( mPackageSetting); + mUserState = new PackageUserStateImpl().setInstalled(true); + mPackageSetting.setUserState(mUserId, mUserState); + when(mPackageState.getUserStateOrDefault(eq(mUserId))).thenReturn(mUserState); when(mContext.getSystemService(LauncherApps.class)).thenReturn(mLauncherApps); when(mLauncherApps.getActivityList(eq(PACKAGE), eq(UserHandle.CURRENT))).thenReturn( mLauncherActivityInfos); @@ -135,9 +153,7 @@ public class PackageArchiverServiceTest { Exception e = assertThrows( SecurityException.class, () -> mArchiveService.requestArchive(PACKAGE, "different", mIntentSender, - UserHandle.CURRENT - ) - ); + UserHandle.CURRENT)); assertThat(e).hasMessageThat().isEqualTo( String.format( "The UID %s of callerPackageName set by the caller doesn't match the " @@ -154,9 +170,7 @@ public class PackageArchiverServiceTest { Exception e = assertThrows( ParcelableException.class, () -> mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, - UserHandle.CURRENT - ) - ); + UserHandle.CURRENT)); assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); assertThat(e.getCause()).hasMessageThat().isEqualTo( String.format("Package %s not found.", PACKAGE)); @@ -169,9 +183,7 @@ public class PackageArchiverServiceTest { Exception e = assertThrows( ParcelableException.class, () -> mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, - UserHandle.CURRENT - ) - ); + UserHandle.CURRENT)); assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); assertThat(e.getCause()).hasMessageThat().isEqualTo( String.format("Package %s not found.", PACKAGE)); @@ -193,25 +205,28 @@ public class PackageArchiverServiceTest { Exception e = assertThrows( ParcelableException.class, () -> mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, - UserHandle.CURRENT - ) - ); + UserHandle.CURRENT)); assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); assertThat(e.getCause()).hasMessageThat().isEqualTo( String.format("No installer found to archive app %s.", PACKAGE)); } @Test - public void archiveApp_success() { - List<ArchiveState.ArchiveActivityInfo> activityInfos = new ArrayList<>(); - for (LauncherActivityInfo mainActivity : createLauncherActivities()) { - // TODO(b/278553670) Extract and store launcher icons - ArchiveState.ArchiveActivityInfo activityInfo = new ArchiveState.ArchiveActivityInfo( - mainActivity.getLabel().toString(), - Path.of("/TODO"), null); - activityInfos.add(activityInfo); - } + public void archiveApp_noMainActivities() { + when(mLauncherApps.getActivityList(eq(PACKAGE), eq(UserHandle.CURRENT))).thenReturn( + List.of()); + Exception e = assertThrows( + ParcelableException.class, + () -> mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, + UserHandle.CURRENT)); + assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); + assertThat(e.getCause()).hasMessageThat().isEqualTo( + TextUtils.formatSimple("The app %s does not have a main activity.", PACKAGE)); + } + + @Test + public void archiveApp_success() { mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, UserHandle.CURRENT); verify(mInstallerService).uninstall( @@ -220,7 +235,112 @@ public class PackageArchiverServiceTest { eq(UserHandle.CURRENT.getIdentifier())); assertThat(mPackageSetting.readUserState( UserHandle.CURRENT.getIdentifier()).getArchiveState()).isEqualTo( - new ArchiveState(activityInfos, CALLER_PACKAGE)); + createArchiveState()); + } + + @Test + public void unarchiveApp_callerPackageNameIncorrect() { + mUserState.setArchiveState(createArchiveState()).setInstalled(false); + + Exception e = assertThrows( + SecurityException.class, + () -> mArchiveService.requestUnarchive(PACKAGE, "different", + UserHandle.CURRENT)); + assertThat(e).hasMessageThat().isEqualTo( + String.format( + "The UID %s of callerPackageName set by the caller doesn't match the " + + "caller's actual UID %s.", + 0, + Binder.getCallingUid())); + } + + @Test + public void unarchiveApp_packageNotInstalled() { + mUserState.setArchiveState(createArchiveState()).setInstalled(false); + when(mComputer.getPackageStateFiltered(eq(PACKAGE), anyInt(), anyInt())).thenReturn( + null); + + Exception e = assertThrows( + ParcelableException.class, + () -> mArchiveService.requestUnarchive(PACKAGE, CALLER_PACKAGE, + UserHandle.CURRENT)); + assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); + assertThat(e.getCause()).hasMessageThat().isEqualTo( + String.format("Package %s not found.", PACKAGE)); + } + + @Test + public void unarchiveApp_notArchived() { + Exception e = assertThrows( + ParcelableException.class, + () -> mArchiveService.requestUnarchive(PACKAGE, CALLER_PACKAGE, + UserHandle.CURRENT)); + assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); + assertThat(e.getCause()).hasMessageThat().isEqualTo( + String.format("Package %s is not currently archived.", PACKAGE)); + } + + @Test + public void unarchiveApp_noInstallerFound() { + mUserState.setArchiveState(createArchiveState()); + InstallSource otherInstallSource = + InstallSource.create( + CALLER_PACKAGE, + CALLER_PACKAGE, + /* installerPackageName= */ null, + Binder.getCallingUid(), + /* updateOwnerPackageName= */ null, + /* installerAttributionTag= */ null, + /* packageSource= */ 0); + when(mPackageState.getInstallSource()).thenReturn(otherInstallSource); + + Exception e = assertThrows( + ParcelableException.class, + () -> mArchiveService.requestUnarchive(PACKAGE, CALLER_PACKAGE, + UserHandle.CURRENT)); + assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class); + assertThat(e.getCause()).hasMessageThat().isEqualTo( + String.format("No installer found to unarchive app %s.", PACKAGE)); + } + + @Test + public void unarchiveApp_success() { + mUserState.setArchiveState(createArchiveState()).setInstalled(false); + + mArchiveService.requestUnarchive(PACKAGE, CALLER_PACKAGE, UserHandle.CURRENT); + mMockSystem.mocks().getHandler().flush(); + + ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(mContext).sendOrderedBroadcastAsUser( + intentCaptor.capture(), + eq(UserHandle.CURRENT), + /* receiverPermission = */ isNull(), + eq(AppOpsManager.OP_NONE), + any(Bundle.class), + /* resultReceiver= */ isNull(), + /* scheduler= */ isNull(), + /* initialCode= */ eq(0), + /* initialData= */ isNull(), + /* initialExtras= */ isNull()); + Intent intent = intentCaptor.getValue(); + assertThat(intent.getFlags() & FLAG_RECEIVER_FOREGROUND).isNotEqualTo(0); + assertThat(intent.getStringExtra(PackageArchiver.EXTRA_UNARCHIVE_PACKAGE_NAME)).isEqualTo( + PACKAGE); + assertThat( + intent.getBooleanExtra(PackageArchiver.EXTRA_UNARCHIVE_ALL_USERS, true)).isFalse(); + assertThat(intent.getPackage()).isEqualTo(INSTALLER_PACKAGE); + } + + private static ArchiveState createArchiveState() { + List<ArchiveState.ArchiveActivityInfo> activityInfos = new ArrayList<>(); + for (LauncherActivityInfo mainActivity : createLauncherActivities()) { + // TODO(b/278553670) Extract and store launcher icons + ArchiveState.ArchiveActivityInfo activityInfo = new ArchiveState.ArchiveActivityInfo( + mainActivity.getLabel().toString(), + Path.of("/TODO"), null); + activityInfos.add(activityInfo); + } + return new ArchiveState(activityInfos, INSTALLER_PACKAGE); } private static List<LauncherActivityInfo> createLauncherActivities() { diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java index 534aa89e1699..93cbea6125fa 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsRule.java @@ -243,8 +243,10 @@ public class BatteryUsageStatsRule implements TestRule { & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0; final boolean includeProcessStateData = (query.getFlags() & BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_PROCESS_STATE_DATA) != 0; + final double minConsumedPowerThreshold = query.getMinConsumedPowerThreshold(); BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder( - customPowerComponentNames, includePowerModels, includeProcessStateData); + customPowerComponentNames, includePowerModels, includeProcessStateData, + minConsumedPowerThreshold); SparseArray<? extends BatteryStats.Uid> uidStats = mBatteryStats.getUidStats(); for (int i = 0; i < uidStats.size(); i++) { builder.getOrCreateUidBatteryConsumerBuilder(uidStats.valueAt(i)); diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java index 266a22632a6d..07c486c6ce58 100644 --- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java +++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java @@ -181,7 +181,7 @@ public class BatteryUsageStatsTest { final BatteryUsageStats stats2 = buildBatteryUsageStats2(new String[]{"FOO"}, true).build(); final BatteryUsageStats sum = - new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true) + new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, 0) .add(stats1) .add(stats2) .build(); @@ -222,7 +222,7 @@ public class BatteryUsageStatsTest { @Test public void testAdd_customComponentMismatch() { final BatteryUsageStats.Builder builder = - new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true); + new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, 0); final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"BAR"}, false).build(); assertThrows(IllegalArgumentException.class, () -> builder.add(stats)); @@ -231,7 +231,7 @@ public class BatteryUsageStatsTest { @Test public void testAdd_processStateDataMismatch() { final BatteryUsageStats.Builder builder = - new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true); + new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, 0); final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"FOO"}, false).build(); assertThrows(IllegalArgumentException.class, () -> builder.add(stats)); @@ -260,7 +260,7 @@ public class BatteryUsageStatsTest { final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks); final BatteryUsageStats.Builder builder = - new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true) + new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true, 0) .setBatteryCapacity(4000) .setDischargePercentage(20) .setDischargedPowerRange(1000, 2000) @@ -305,7 +305,7 @@ public class BatteryUsageStatsTest { final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(customPowerComponentNames, true, - includeProcessStateData); + includeProcessStateData, 0); builder.setDischargePercentage(30) .setDischargedPowerRange(1234, 2345) .setStatsStartTimestamp(2000) diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_false.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_false.xml new file mode 100644 index 000000000000..4785a881638f --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_false.xml @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <keep-profiles-running value="false" /> + <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"> + <policies flags="991" /> + <strong-auth-unlock-timeout value="0" /> + <organization-color value="-16738680" /> + <active-password value="0" /> + </admin> +</policies> diff --git a/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_true.xml b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_true.xml new file mode 100644 index 000000000000..07ec229fa267 --- /dev/null +++ b/services/tests/servicestests/assets/PolicyVersionUpgraderTest/device_policies_keep_profiles_running_true.xml @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='utf-8' standalone='yes' ?> +<policies setup-complete="true" provisioning-state="3"> + <keep-profiles-running value="true" /> + <admin name="com.android.frameworks.servicestests/com.android.server.devicepolicy.DummyDeviceAdmins$Admin1"> + <policies flags="991" /> + <strong-auth-unlock-timeout value="0" /> + <organization-color value="-16738680" /> + <active-password value="0" /> + </admin> +</policies> diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java index a621c0c01067..0b730f139f3e 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java @@ -21,6 +21,7 @@ import static com.android.server.biometrics.AuthenticationStatsCollector.MAXIMUM import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.anyString; @@ -78,6 +79,8 @@ public class AuthenticationStatsCollectorTest { @Mock private SharedPreferences mSharedPreferences; @Mock + private SharedPreferences.Editor mEditor; + @Mock private BiometricNotification mBiometricNotification; @Before @@ -99,6 +102,8 @@ public class AuthenticationStatsCollectorTest { when(mContext.getSharedPreferences(any(File.class), anyInt())) .thenReturn(mSharedPreferences); when(mSharedPreferences.getStringSet(anyString(), anySet())).thenReturn(emptySet()); + when(mSharedPreferences.edit()).thenReturn(mEditor); + when(mEditor.putFloat(anyString(), anyFloat())).thenReturn(mEditor); mAuthenticationStatsCollector = new AuthenticationStatsCollector(mContext, 0 /* modality */, mBiometricNotification); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsPersisterTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsPersisterTest.java index 0c0d47a6b165..32c55ebcb674 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsPersisterTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsPersisterTest.java @@ -19,6 +19,7 @@ package com.android.server.biometrics; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.anyString; @@ -63,6 +64,8 @@ public class AuthenticationStatsPersisterTest { private static final String FINGERPRINT_REJECTIONS = "fingerprint_rejections"; private static final String ENROLLMENT_NOTIFICATIONS = "enrollment_notifications"; private static final String KEY = "frr_stats"; + private static final String THRESHOLD_KEY = "frr_threshold"; + private static final float FRR_THRESHOLD = 0.25f; @Mock private Context mContext; @@ -74,6 +77,8 @@ public class AuthenticationStatsPersisterTest { @Captor private ArgumentCaptor<Set<String>> mStringSetArgumentCaptor; + @Captor + private ArgumentCaptor<Float> mFrrThresholdArgumentCaptor; @Before public void setUp() { @@ -81,6 +86,7 @@ public class AuthenticationStatsPersisterTest { .thenReturn(mSharedPreferences); when(mSharedPreferences.edit()).thenReturn(mEditor); when(mEditor.putStringSet(anyString(), anySet())).thenReturn(mEditor); + when(mEditor.putFloat(anyString(), anyFloat())).thenReturn(mEditor); mAuthenticationStatsPersister = new AuthenticationStatsPersister(mContext); } @@ -255,6 +261,14 @@ public class AuthenticationStatsPersisterTest { assertThat(mStringSetArgumentCaptor.getValue()).doesNotContain(authenticationStats); } + @Test + public void persistFrrThreshold_shouldUpdateRecord() { + mAuthenticationStatsPersister.persistFrrThreshold(FRR_THRESHOLD); + + verify(mEditor).putFloat(eq(THRESHOLD_KEY), mFrrThresholdArgumentCaptor.capture()); + assertThat(mFrrThresholdArgumentCaptor.getValue()).isWithin(0f).of(FRR_THRESHOLD); + } + private String buildFrrStats(AuthenticationStats authenticationStats) throws JSONException { if (authenticationStats.getModality() == BiometricsProtoEnums.MODALITY_FACE) { diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 00e35ecece8b..41af9e31dbdd 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -129,7 +129,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import java.util.ArrayList; import java.util.Arrays; import java.util.Set; import java.util.function.Consumer; @@ -296,19 +295,20 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices= */ true, targetDisplayCategory); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); return blockedAppIntent; } - private ArrayList<ActivityInfo> getActivityInfoList( + private ActivityInfo getActivityInfo( String packageName, String name, boolean displayOnRemoveDevices, String requiredDisplayCategory) { ActivityInfo activityInfo = new ActivityInfo(); @@ -318,7 +318,7 @@ public class VirtualDeviceManagerServiceTest { ? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES; activityInfo.applicationInfo = mApplicationInfoMock; activityInfo.requiredDisplayCategory = requiredDisplayCategory; - return new ArrayList<>(Arrays.asList(activityInfo)); + return activityInfo; } @Before @@ -1414,14 +1414,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext, never()).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1434,14 +1435,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( PERMISSION_CONTROLLER_PACKAGE_NAME, PERMISSION_CONTROLLER_PACKAGE_NAME, /* displayOnRemoveDevices */ false, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1454,14 +1456,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( SETTINGS_PACKAGE_NAME, SETTINGS_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1474,14 +1477,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( VENDING_PACKAGE_NAME, VENDING_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1494,14 +1498,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( GOOGLE_DIALER_PACKAGE_NAME, GOOGLE_DIALER_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1514,14 +1519,15 @@ public class VirtualDeviceManagerServiceTest { DISPLAY_ID_1); doNothing().when(mContext).startActivityAsUser(any(), any(), any()); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( GOOGLE_MAPS_PACKAGE_NAME, GOOGLE_MAPS_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( - activityInfos.get(0), mAssociationInfo.getDisplayName()); - gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN); + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); verify(mContext).startActivityAsUser(argThat(intent -> intent.filterEquals(blockedAppIntent)), any(), any()); @@ -1561,12 +1567,12 @@ public class VirtualDeviceManagerServiceTest { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( DISPLAY_ID_1); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true, /* targetDisplayCategory */ null); - assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent, + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) .isTrue(); } @@ -1585,7 +1591,7 @@ public class VirtualDeviceManagerServiceTest { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( DISPLAY_ID_1); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true, @@ -1597,7 +1603,7 @@ public class VirtualDeviceManagerServiceTest { // register interceptor and intercept intent mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter); - assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent, + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) .isFalse(); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -1609,7 +1615,7 @@ public class VirtualDeviceManagerServiceTest { // unregister interceptor and launch activity mDeviceImpl.unregisterIntentInterceptor(interceptor); - assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent, + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) .isTrue(); } @@ -1628,7 +1634,7 @@ public class VirtualDeviceManagerServiceTest { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( DISPLAY_ID_1); - ArrayList<ActivityInfo> activityInfos = getActivityInfoList( + ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true, @@ -1640,7 +1646,7 @@ public class VirtualDeviceManagerServiceTest { // register interceptor with different filter mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter); - assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent, + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) .isTrue(); } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index f408ef0394e2..f4dac2c10d0f 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -1144,6 +1144,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { eq(UserManager.DISALLOW_ADD_CLONE_PROFILE), eq(true), eq(UserHandle.SYSTEM)); + verify(getServices().userManager, times(1)).setUserRestriction( + eq(UserManager.DISALLOW_ADD_PRIVATE_PROFILE), + eq(true), eq(UserHandle.SYSTEM)); + verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); @@ -1422,6 +1426,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { .setUserRestriction(eq(UserManager.DISALLOW_ADD_CLONE_PROFILE), eq(false), MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); + verify(getServices().userManager) + .setUserRestriction(eq(UserManager.DISALLOW_ADD_PRIVATE_PROFILE), eq(false), + MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); + verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(), MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java index eb2ee35161ff..d2b921deb0d9 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/PolicyVersionUpgraderTest.java @@ -76,7 +76,7 @@ import javax.xml.parsers.DocumentBuilderFactory; public class PolicyVersionUpgraderTest extends DpmTestBase { // NOTE: Only change this value if the corresponding CL also adds a test to test the upgrade // to the new version. - private static final int LATEST_TESTED_VERSION = 5; + private static final int LATEST_TESTED_VERSION = 6; public static final String PERMISSIONS_TAG = "admin-can-grant-sensors-permissions"; public static final String DEVICE_OWNER_XML = "device_owner_2.xml"; private ComponentName mFakeAdmin; @@ -313,7 +313,7 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { } @Test - public void testEffectiveKeepProfilesRunningSet() throws Exception { + public void testEffectiveKeepProfilesRunningSetToFalse4To5() throws Exception { writeVersionToXml(4); final int userId = UserHandle.USER_SYSTEM; @@ -327,10 +327,111 @@ public class PolicyVersionUpgraderTest extends DpmTestBase { Document policies = readPolicies(userId); Element keepProfilesRunning = (Element) policies.getDocumentElement() .getElementsByTagName("keep-profiles-running").item(0); - assertThat(keepProfilesRunning.getAttribute("value")).isEqualTo("false"); + + // Default value (false) is not serialized. + assertThat(keepProfilesRunning).isNull(); + } + @Test + public void testEffectiveKeepProfilesRunningIsToFalse4To6() throws Exception { + writeVersionToXml(4); + + final int userId = UserHandle.USER_SYSTEM; + mProvider.mUsers = new int[]{userId}; + preparePoliciesFile(userId, "device_policies.xml"); + + mUpgrader.upgradePolicy(6); + + assertThat(readVersionFromXml()).isAtLeast(6); + + Document policies = readPolicies(userId); + Element keepProfilesRunning = (Element) policies.getDocumentElement() + .getElementsByTagName("keep-profiles-running").item(0); + + // Default value (false) is not serialized. + assertThat(keepProfilesRunning).isNull(); + } + + /** + * Verify correct behaviour when upgrading from Android 13 + */ + @Test + public void testEffectiveKeepProfilesRunningIsToFalse3To6() throws Exception { + writeVersionToXml(3); + + final int userId = UserHandle.USER_SYSTEM; + mProvider.mUsers = new int[]{userId}; + preparePoliciesFile(userId, "device_policies.xml"); + + mUpgrader.upgradePolicy(6); + + assertThat(readVersionFromXml()).isAtLeast(6); + + Document policies = readPolicies(userId); + Element keepProfilesRunning = (Element) policies.getDocumentElement() + .getElementsByTagName("keep-profiles-running").item(0); + + // Default value (false) is not serialized. + assertThat(keepProfilesRunning).isNull(); } @Test + public void testEffectiveKeepProfilesRunningMissingInV5() throws Exception { + writeVersionToXml(5); + + final int userId = UserHandle.USER_SYSTEM; + mProvider.mUsers = new int[]{userId}; + preparePoliciesFile(userId, "device_policies.xml"); + + mUpgrader.upgradePolicy(6); + + assertThat(readVersionFromXml()).isAtLeast(6); + + Document policies = readPolicies(userId); + Element keepProfilesRunning = (Element) policies.getDocumentElement() + .getElementsByTagName("keep-profiles-running").item(0); + assertThat(keepProfilesRunning.getAttribute("value")).isEqualTo("true"); + } + + @Test + public void testEffectiveKeepProfilesRunningTrueInV5() throws Exception { + writeVersionToXml(5); + + final int userId = UserHandle.USER_SYSTEM; + mProvider.mUsers = new int[]{userId}; + preparePoliciesFile(userId, "device_policies_keep_profiles_running_true.xml"); + + mUpgrader.upgradePolicy(6); + + assertThat(readVersionFromXml()).isAtLeast(6); + + Document policies = readPolicies(userId); + Element keepProfilesRunning = (Element) policies.getDocumentElement() + .getElementsByTagName("keep-profiles-running").item(0); + assertThat(keepProfilesRunning.getAttribute("value")).isEqualTo("true"); + } + + @Test + public void testEffectiveKeepProfilesRunningFalseInV5() throws Exception { + writeVersionToXml(5); + + final int userId = UserHandle.USER_SYSTEM; + mProvider.mUsers = new int[]{userId}; + preparePoliciesFile(userId, "device_policies_keep_profiles_running_false.xml"); + + mUpgrader.upgradePolicy(6); + + assertThat(readVersionFromXml()).isAtLeast(6); + + Document policies = readPolicies(userId); + Element keepProfilesRunning = (Element) policies.getDocumentElement() + .getElementsByTagName("keep-profiles-running").item(0); + + // Default value (false) is not serialized. + assertThat(keepProfilesRunning).isNull(); + } + + + @Test public void isLatestVersionTested() { assertThat(DevicePolicyManagerService.DPMS_VERSION).isEqualTo(LATEST_TESTED_VERSION); } diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java index ecd35a55e291..b22798e6eaed 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java @@ -1174,6 +1174,24 @@ public final class UserManagerTest { } } + // Make sure the creation of a private profile fails if DISALLOW_ADD_PRIVATE_PROFILE is true. + @MediumTest + @Test + public void testCreateProfileForUser_disallowAddPrivateProfile() { + final int mainUserId = ActivityManager.getCurrentUser(); + final UserHandle mainUserHandle = asHandle(mainUserId); + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, + true, mainUserHandle); + try { + UserInfo privateProfileInfo = createProfileForUser("Private", + UserManager.USER_TYPE_PROFILE_PRIVATE, mainUserId); + assertThat(privateProfileInfo).isNull(); + } finally { + mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, false, + mainUserHandle); + } + } + @MediumTest @Test public void testAddRestrictedProfile() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java index a387d4a8b2bc..9907bd6f38b6 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java @@ -72,6 +72,8 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { public void testCanDeviceOwnerChange() { assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_RECORD_AUDIO)); assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_WALLPAPER)); + assertFalse(UserRestrictionsUtils.canDeviceOwnerChange( + UserManager.DISALLOW_ADD_PRIVATE_PROFILE)); assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_ADD_USER)); assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_USER_SWITCH)); } @@ -83,6 +85,8 @@ public class UserRestrictionsUtilsTest extends AndroidTestCase { UserManager.DISALLOW_WALLPAPER, true)); assertFalse(UserRestrictionsUtils.canProfileOwnerChange( UserManager.DISALLOW_USER_SWITCH, true)); + assertFalse(UserRestrictionsUtils.canProfileOwnerChange( + UserManager.DISALLOW_ADD_PRIVATE_PROFILE, true)); assertTrue(UserRestrictionsUtils.canProfileOwnerChange( UserManager.DISALLOW_ADD_USER, true)); assertTrue(UserRestrictionsUtils.canProfileOwnerChange( diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java index 10b49c67e8bb..bc826a3cf4a6 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java @@ -30,7 +30,6 @@ import static org.mockito.Mockito.when; import android.content.res.Resources; import android.os.VibrationEffect; -import android.os.Vibrator; import android.os.VibratorInfo; import android.util.AtomicFile; import android.util.SparseArray; @@ -73,12 +72,10 @@ public class HapticFeedbackCustomizationTest { VibrationEffect.createWaveform(new long[] {123}, new int[] {254}, -1); @Mock private Resources mResourcesMock; - @Mock private Vibrator mVibratorMock; @Mock private VibratorInfo mVibratorInfoMock; @Before public void setUp() { - when(mVibratorMock.getInfo()).thenReturn(mVibratorInfoMock); when(mVibratorInfoMock.areVibrationFeaturesSupported(any())).thenReturn(true); } @@ -220,17 +217,17 @@ public class HapticFeedbackCustomizationTest { public void testParseCustomizations_noCustomizationFile_returnsNull() throws Exception { setCustomizationFilePath(""); - assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock)) + assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock)) .isNull(); setCustomizationFilePath(null); - assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock)) + assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock)) .isNull(); setCustomizationFilePath("non_existent_file.xml"); - assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock)) + assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock)) .isNull(); } @@ -387,7 +384,7 @@ public class HapticFeedbackCustomizationTest { String xml, SparseArray<VibrationEffect> expectedCustomizations) throws Exception { setupCustomizationFile(xml); assertThat(expectedCustomizations.contentEquals( - HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock))) + HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock))) .isTrue(); } @@ -395,13 +392,15 @@ public class HapticFeedbackCustomizationTest { setupCustomizationFile(xml); assertThrows("Expected haptic feedback customization to fail for " + xml, CustomizationParserException.class, - () -> HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock)); + () -> HapticFeedbackCustomization.loadVibrations( + mResourcesMock, mVibratorInfoMock)); } private void assertParseCustomizationsFails() throws Exception { assertThrows("Expected haptic feedback customization to fail", CustomizationParserException.class, - () -> HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorMock)); + () -> HapticFeedbackCustomization.loadVibrations( + mResourcesMock, mVibratorInfoMock)); } private void setupCustomizationFile(String xml) throws Exception { diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java index cae811e9bb35..a91bd2b55f76 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java @@ -31,8 +31,10 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; +import android.hardware.vibrator.IVibrator; +import android.os.VibrationAttributes; import android.os.VibrationEffect; -import android.os.test.FakeVibrator; +import android.os.VibratorInfo; import android.util.AtomicFile; import android.util.SparseArray; @@ -58,7 +60,7 @@ public class HapticFeedbackVibrationProviderTest { VibrationEffect.startComposition().addPrimitive(PRIMITIVE_CLICK, 0.3497f).compose(); private Context mContext = InstrumentationRegistry.getContext(); - private FakeVibrator mVibrator = new FakeVibrator(mContext); + private VibratorInfo mVibratorInfo = VibratorInfo.EMPTY_VIBRATOR_INFO; @Mock private Resources mResourcesMock; @@ -66,14 +68,14 @@ public class HapticFeedbackVibrationProviderTest { public void testNonExistentCustomization_useDefault() throws Exception { // No customization file is set. HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK)) .isEqualTo(VibrationEffect.get(EFFECT_TICK)); // The customization file specifies no customization. setupCustomizationFile("<haptic-feedback-constants></haptic-feedback-constants>"); - hapticProvider = new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator); + hapticProvider = new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK)) .isEqualTo(VibrationEffect.get(EFFECT_TICK)); @@ -83,7 +85,7 @@ public class HapticFeedbackVibrationProviderTest { public void testExceptionParsingCustomizations_useDefault() throws Exception { setupCustomizationFile("<bad-xml></bad-xml>"); HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK)) .isEqualTo(VibrationEffect.get(EFFECT_TICK)); @@ -96,7 +98,7 @@ public class HapticFeedbackVibrationProviderTest { customizations.put(CONTEXT_CLICK, PRIMITIVE_CLICK_EFFECT); HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations); // The override for `CONTEXT_CLICK` is used. assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK)) @@ -109,11 +111,15 @@ public class HapticFeedbackVibrationProviderTest { @Test public void testDoNotUseInvalidCustomizedVibration() throws Exception { mockVibratorPrimitiveSupport(new int[] {}); - SparseArray<VibrationEffect> customizations = new SparseArray<>(); - customizations.put(CONTEXT_CLICK, PRIMITIVE_CLICK_EFFECT); + String xml = "<haptic-feedback-constants>" + + "<constant id=\"" + CONTEXT_CLICK + "\">" + + PRIMITIVE_CLICK_EFFECT + + "</constant>" + + "</haptic-feedback-constants>"; + setupCustomizationFile(xml); HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); // The override for `CONTEXT_CLICK` is not used because the vibration is not supported. assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK)) @@ -132,14 +138,14 @@ public class HapticFeedbackVibrationProviderTest { // Test with a customization available for `TEXT_HANDLE_MOVE`. HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations); assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)).isNull(); // Test with no customization available for `TEXT_HANDLE_MOVE`. hapticProvider = new HapticFeedbackVibrationProvider( - mResourcesMock, mVibrator, /* hapticCustomizations= */ null); + mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null); assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)).isNull(); } @@ -153,7 +159,7 @@ public class HapticFeedbackVibrationProviderTest { // Test with a customization available for `TEXT_HANDLE_MOVE`. HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations); assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)) .isEqualTo(PRIMITIVE_CLICK_EFFECT); @@ -161,7 +167,7 @@ public class HapticFeedbackVibrationProviderTest { // Test with no customization available for `TEXT_HANDLE_MOVE`. hapticProvider = new HapticFeedbackVibrationProvider( - mResourcesMock, mVibrator, /* hapticCustomizations= */ null); + mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null); assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)) .isEqualTo(VibrationEffect.get(EFFECT_TEXTURE_TICK)); @@ -176,14 +182,14 @@ public class HapticFeedbackVibrationProviderTest { customizations.put(SAFE_MODE_ENABLED, PRIMITIVE_CLICK_EFFECT); HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations); assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)) .isEqualTo(PRIMITIVE_CLICK_EFFECT); mockSafeModeEnabledVibration(null); hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations); assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)) .isEqualTo(PRIMITIVE_CLICK_EFFECT); @@ -193,20 +199,9 @@ public class HapticFeedbackVibrationProviderTest { public void testNoValidCustomizationPresentForSafeModeEnabled_resourceBasedVibrationUsed() throws Exception { mockSafeModeEnabledVibration(10, 20, 30, 40); - SparseArray<VibrationEffect> customizations = new SparseArray<>(); - customizations.put(SAFE_MODE_ENABLED, PRIMITIVE_CLICK_EFFECT); - - // Test with a customization that is not supported by the vibrator. HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); - - assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)) - .isEqualTo(VibrationEffect.createWaveform(new long[] {10, 20, 30, 40}, -1)); - - // Test with no customizations. - hapticProvider = new HapticFeedbackVibrationProvider( - mResourcesMock, mVibrator, /* hapticCustomizations= */ null); + mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null); assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)) .isEqualTo(VibrationEffect.createWaveform(new long[] {10, 20, 30, 40}, -1)); @@ -216,25 +211,44 @@ public class HapticFeedbackVibrationProviderTest { public void testNoValidCustomizationAndResourcePresentForSafeModeEnabled_noVibrationUsed() throws Exception { mockSafeModeEnabledVibration(null); - SparseArray<VibrationEffect> customizations = new SparseArray<>(); - customizations.put(SAFE_MODE_ENABLED, PRIMITIVE_CLICK_EFFECT); - - // Test with a customization that is not supported by the vibrator. HapticFeedbackVibrationProvider hapticProvider = - new HapticFeedbackVibrationProvider(mResourcesMock, mVibrator, customizations); + new HapticFeedbackVibrationProvider( + mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null); assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)).isNull(); + } - // Test with no customizations. - hapticProvider = - new HapticFeedbackVibrationProvider( - mResourcesMock, mVibrator, /* hapticCustomizations= */ null); + @Test + public void testVibrationAttribute_forNotBypassingIntensitySettings() { + HapticFeedbackVibrationProvider hapticProvider = + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); - assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)).isNull(); + VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( + SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false); + + assertThat(attrs.getFlags() & VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF) + .isEqualTo(0); + } + + @Test + public void testVibrationAttribute_forByassingIntensitySettings() { + HapticFeedbackVibrationProvider hapticProvider = + new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo); + + VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( + SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true); + + assertThat(attrs.getFlags() & VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF) + .isNotEqualTo(0); } private void mockVibratorPrimitiveSupport(int... supportedPrimitives) { - mVibrator = new FakeVibrator(mContext, supportedPrimitives); + VibratorInfo.Builder builder = new VibratorInfo.Builder(/* id= */ 1) + .setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS); + for (int primitive : supportedPrimitives) { + builder.setSupportedPrimitive(primitive, 10); + } + mVibratorInfo = builder.build(); } private void mockHapticTextSupport(boolean supported) { diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java index 4e3a893954a2..c25f0cb91caa 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -30,6 +31,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -45,6 +47,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageManagerInternal; +import android.content.res.Resources; import android.hardware.input.IInputManager; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; @@ -79,8 +82,10 @@ import android.os.vibrator.VibrationConfig; import android.os.vibrator.VibrationEffectSegment; import android.provider.Settings; import android.util.ArraySet; +import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.Display; +import android.view.HapticFeedbackConstants; import android.view.InputDevice; import androidx.test.InstrumentationRegistry; @@ -169,6 +174,8 @@ public class VibratorManagerServiceTest { private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>(); + private SparseArray<VibrationEffect> mHapticFeedbackVibrationMap = new SparseArray<>(); + private VibratorManagerService mService; private Context mContextSpy; private TestLooper mTestLooper; @@ -309,6 +316,12 @@ public class VibratorManagerServiceTest { mExternalVibratorService = (VibratorManagerService.ExternalVibratorService) serviceInstance; } + + HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider( + Resources resources, VibratorInfo vibratorInfo) { + return new HapticFeedbackVibrationProvider( + resources, vibratorInfo, mHapticFeedbackVibrationMap); + } }); return mService; } @@ -623,6 +636,18 @@ public class VibratorManagerServiceTest { } @Test + public void vibrate_withoutVibratePermission_throwsSecurityException() { + denyPermission(android.Manifest.permission.VIBRATE); + VibratorManagerService service = createSystemReadyService(); + + assertThrows("Expected vibrating without permission to fail!", + SecurityException.class, + () -> vibrate(service, + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK), + VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH))); + } + + @Test public void vibrate_withRingtone_usesRingerModeSettings() throws Exception { mockVibrators(1); FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); @@ -1274,6 +1299,60 @@ public class VibratorManagerServiceTest { } @Test + public void performHapticFeedback_doesNotRequirePermission() throws Exception { + denyPermission(android.Manifest.permission.VIBRATE); + mHapticFeedbackVibrationMap.put( + HapticFeedbackConstants.KEYBOARD_TAP, + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); + mockVibrators(1); + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); + fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); + VibratorManagerService service = createSystemReadyService(); + + HalVibration vibration = + performHapticFeedbackAndWaitUntilFinished( + service, HapticFeedbackConstants.KEYBOARD_TAP, /* always= */ true); + + List<VibrationEffectSegment> playedSegments = fakeVibrator.getAllEffectSegments(); + assertEquals(1, playedSegments.size()); + PrebakedSegment segment = (PrebakedSegment) playedSegments.get(0); + assertEquals(VibrationEffect.EFFECT_CLICK, segment.getEffectId()); + assertEquals(VibrationAttributes.USAGE_TOUCH, vibration.callerInfo.attrs.getUsage()); + } + + @Test + public void performHapticFeedback_doesNotVibrateWhenVibratorInfoNotReady() throws Exception { + denyPermission(android.Manifest.permission.VIBRATE); + mHapticFeedbackVibrationMap.put( + HapticFeedbackConstants.KEYBOARD_TAP, + VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK)); + mockVibrators(1); + FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1); + fakeVibrator.setVibratorInfoLoadSuccessful(false); + fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK); + VibratorManagerService service = createService(); + + performHapticFeedbackAndWaitUntilFinished( + service, HapticFeedbackConstants.KEYBOARD_TAP, /* always= */ true); + + assertTrue(fakeVibrator.getAllEffectSegments().isEmpty()); + } + + @Test + public void performHapticFeedback_doesNotVibrateForInvalidConstant() throws Exception { + denyPermission(android.Manifest.permission.VIBRATE); + mockVibrators(1); + VibratorManagerService service = createSystemReadyService(); + + // These are bad haptic feedback IDs, so expect no vibration played. + performHapticFeedbackAndWaitUntilFinished(service, /* constant= */ -1, /* always= */ false); + performHapticFeedbackAndWaitUntilFinished( + service, HapticFeedbackConstants.NO_HAPTICS, /* always= */ true); + + assertTrue(mVibratorProviders.get(1).getAllEffectSegments().isEmpty()); + } + + @Test public void vibrate_withIntensitySettings_appliesSettingsToScaleVibrations() throws Exception { int defaultNotificationIntensity = mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION); @@ -2231,6 +2310,18 @@ public class VibratorManagerServiceTest { mContextSpy.getContentResolver(), settingName, value, UserHandle.USER_CURRENT); } + private HalVibration performHapticFeedbackAndWaitUntilFinished(VibratorManagerService service, + int constant, boolean always) throws InterruptedException { + HalVibration vib = + service.performHapticFeedbackInternal(UID, Display.DEFAULT_DISPLAY, PACKAGE_NAME, + constant, always, "some reason", service); + if (vib != null) { + vib.waitForEnd(); + } + + return vib; + } + private void vibrateAndWaitUntilFinished(VibratorManagerService service, VibrationEffect effect, VibrationAttributes attrs) throws InterruptedException { vibrateAndWaitUntilFinished(service, CombinedVibration.createParallel(effect), attrs); @@ -2239,8 +2330,8 @@ public class VibratorManagerServiceTest { private void vibrateAndWaitUntilFinished(VibratorManagerService service, CombinedVibration effect, VibrationAttributes attrs) throws InterruptedException { HalVibration vib = - service.vibrateInternal(UID, Display.DEFAULT_DISPLAY, PACKAGE_NAME, effect, attrs, - "some reason", service); + service.vibrateWithPermissionCheck(UID, Display.DEFAULT_DISPLAY, PACKAGE_NAME, + effect, attrs, "some reason", service); if (vib != null) { vib.waitForEnd(); } @@ -2271,4 +2362,9 @@ public class VibratorManagerServiceTest { } return predicateResult; } + + private void denyPermission(String permission) { + doThrow(new SecurityException()).when(mContextSpy) + .enforceCallingOrSelfPermission(eq(permission), anyString()); + } } diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java index 8fadecd0dc38..e13dc3eea729 100644 --- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java @@ -65,6 +65,12 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase { KeyboardLogEvent.RECENT_APPS, KeyEvent.KEYCODE_TAB, ALT_ON}, {"BACK key -> Go back", new int[]{KeyEvent.KEYCODE_BACK}, KeyboardLogEvent.BACK, KeyEvent.KEYCODE_BACK, 0}, + {"Meta + `(grave) -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_GRAVE}, + KeyboardLogEvent.BACK, KeyEvent.KEYCODE_GRAVE, META_ON}, + {"Meta + Left arrow -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DPAD_LEFT}, + KeyboardLogEvent.BACK, KeyEvent.KEYCODE_DPAD_LEFT, META_ON}, + {"Meta + Del -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DEL}, + KeyboardLogEvent.BACK, KeyEvent.KEYCODE_DEL, META_ON}, {"APP_SWITCH key -> Open App switcher", new int[]{KeyEvent.KEYCODE_APP_SWITCH}, KeyboardLogEvent.APP_SWITCH, KeyEvent.KEYCODE_APP_SWITCH, 0}, {"ASSIST key -> Launch assistant", new int[]{KeyEvent.KEYCODE_ASSIST}, diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java index bcb0c6b5c269..0989db4c25ac 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStartInterceptorTest.java @@ -59,6 +59,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.Presubmit; import android.testing.DexmakerShareClassLoaderRule; +import android.util.Pair; import android.util.SparseArray; import androidx.test.filters.SmallTest; @@ -128,6 +129,8 @@ public class ActivityStartInterceptorTest { private ActivityManagerInternal mAmInternal; @Mock private LockTaskController mLockTaskController; + @Mock + private TaskDisplayArea mTaskDisplayArea; private ActivityStartInterceptor mInterceptor; private ActivityInfo mAInfo = new ActivityInfo(); @@ -139,8 +142,8 @@ public class ActivityStartInterceptorTest { public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); mService.mAmInternal = mAmInternal; - mInterceptor = new ActivityStartInterceptor( - mService, mSupervisor, mRootWindowContainer, mContext); + mService.mRootWindowContainer = mRootWindowContainer; + mInterceptor = new ActivityStartInterceptor(mService, mSupervisor, mContext); mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID, TEST_START_FLAGS, TEST_CALLING_PACKAGE, null); @@ -201,7 +204,7 @@ public class ActivityStartInterceptorTest { .thenReturn(PLATFORM_PACKAGE_NAME); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // THEN the returned intent is the admin support intent assertEquals(ADMIN_SUPPORT_INTENT, mInterceptor.mIntent); @@ -212,7 +215,7 @@ public class ActivityStartInterceptorTest { final String suspendingPackage = "com.test.suspending.package"; final SuspendDialogInfo dialogInfo = suspendPackage(suspendingPackage); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // Check intent parameters assertEquals(dialogInfo, @@ -243,7 +246,7 @@ public class ActivityStartInterceptorTest { TEST_USER_ID, TEST_PACKAGE_NAME, LOCK_TASK_LAUNCH_MODE_DEFAULT)) .thenReturn(false); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); assertTrue(BlockedAppActivity.createIntent(TEST_USER_ID, TEST_PACKAGE_NAME) .filterEquals(mInterceptor.mIntent)); @@ -257,7 +260,8 @@ public class ActivityStartInterceptorTest { when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(true); // THEN calling intercept returns false because package also has to be suspended. - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertFalse( + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); } @Test @@ -268,7 +272,7 @@ public class ActivityStartInterceptorTest { when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(false); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -284,7 +288,7 @@ public class ActivityStartInterceptorTest { when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(true); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -300,7 +304,7 @@ public class ActivityStartInterceptorTest { when(mDevicePolicyManager.isKeepProfilesRunningEnabled()).thenReturn(false); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // THEN the returned intent is the quiet mode intent assertTrue(UnlaunchableAppActivity.createInQuietModeDialogIntent(TEST_USER_ID) @@ -313,7 +317,7 @@ public class ActivityStartInterceptorTest { when(mAmInternal.shouldConfirmCredentials(TEST_USER_ID)).thenReturn(true); // THEN calling intercept returns true - mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null); // THEN the returned intent is the confirm credentials intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); @@ -329,7 +333,7 @@ public class ActivityStartInterceptorTest { mAInfo.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED; // THEN calling intercept returns true - mInterceptor.intercept(originalIntent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(originalIntent, null, mAInfo, null, null, null, 0, 0, null, null); // THEN the returned intent is original intent assertSame(originalIntent, mInterceptor.mIntent); @@ -345,7 +349,7 @@ public class ActivityStartInterceptorTest { mAInfo.directBootAware = false; // THEN calling intercept returns true - mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null); // THEN the returned intent is the confirm credentials intent assertTrue(CONFIRM_CREDENTIALS_INTENT.filterEquals(mInterceptor.mIntent)); @@ -362,7 +366,7 @@ public class ActivityStartInterceptorTest { mAInfo.directBootAware = true; // THEN calling intercept returns true - mInterceptor.intercept(originalIntent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(originalIntent, null, mAInfo, null, null, null, 0, 0, null, null); // THEN the returned intent is original intent assertSame(originalIntent, mInterceptor.mIntent); @@ -375,7 +379,7 @@ public class ActivityStartInterceptorTest { .thenReturn("This app is bad"); // THEN calling intercept returns true - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); // THEN the returned intent is the harmful app warning intent assertEquals(HarmfulAppWarningActivity.class.getName(), @@ -383,11 +387,40 @@ public class ActivityStartInterceptorTest { } @Test + public void testHomeIntentInterception() { + // GIVEN a primary home intent and a display area that doesn't support it but supports + // secondary home activities + Intent originalIntent = new Intent(Intent.ACTION_MAIN); + originalIntent.addCategory(Intent.CATEGORY_HOME); + + Intent expectedIntent = new Intent(Intent.ACTION_MAIN); + expectedIntent.addCategory(Intent.CATEGORY_SECONDARY_HOME); + expectedIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + final int secondaryDisplayId = 7; + when(mTaskDisplayArea.getDisplayId()).thenReturn(secondaryDisplayId); + when(mRootWindowContainer.shouldPlacePrimaryHomeOnDisplay(eq(secondaryDisplayId))) + .thenReturn(false); + when(mRootWindowContainer.shouldPlaceSecondaryHomeOnDisplayArea(eq(mTaskDisplayArea))) + .thenReturn(true); + when(mRootWindowContainer.resolveSecondaryHomeActivity( + eq(TEST_USER_ID), eq(mTaskDisplayArea))) + .thenReturn(Pair.create(null, expectedIntent)); + + // THEN calling intercept returns true + assertTrue(mInterceptor.intercept(originalIntent, null, mAInfo, null, null, null, 0, 0, + null, mTaskDisplayArea)); + + // THEN the returned intent is the secondary home intent + assertSame(expectedIntent, mInterceptor.mIntent); + } + + @Test public void testNoInterception() { // GIVEN that none of the interception conditions are met // THEN calling intercept returns false - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); } public void addMockInterceptorCallback( @@ -420,7 +453,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); } @@ -429,7 +462,7 @@ public class ActivityStartInterceptorTest { public void testInterceptionCallback_singleCallbackReturnsNull() { addMockInterceptorCallback(null, null); - assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertFalse(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); } @Test @@ -437,7 +470,7 @@ public class ActivityStartInterceptorTest { addMockInterceptorCallback(null, null); addMockInterceptorCallback(new Intent("android.test.second"), null); - assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null)); assertEquals("android.test.second", mInterceptor.mIntent.getAction()); } @@ -447,7 +480,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3), true); ActivityInfo aInfo = mAInfo; - assertTrue(mInterceptor.intercept(null, null, aInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, aInfo, null, null, null, 0, 0, null, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); assertEquals(aInfo, mInterceptor.mAInfo); // mAInfo should not be resolved @@ -459,7 +492,7 @@ public class ActivityStartInterceptorTest { new Intent("android.test.foo"), ActivityOptions.makeBasic().setLaunchDisplayId(3)); ActivityInfo aInfo = mAInfo; - assertTrue(mInterceptor.intercept(null, null, aInfo, null, null, null, 0, 0, null)); + assertTrue(mInterceptor.intercept(null, null, aInfo, null, null, null, 0, 0, null, null)); assertEquals("android.test.foo", mInterceptor.mIntent.getAction()); assertEquals(3, mInterceptor.mActivityOptions.getLaunchDisplayId()); assertNotEquals(aInfo, mInterceptor.mAInfo); // mAInfo should be resolved after intercept @@ -488,7 +521,7 @@ public class ActivityStartInterceptorTest { when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock); Intent intent = new Intent().setAction(ACTION_START_SANDBOXED_ACTIVITY); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); verify(spyCallback, times(1)).onInterceptActivityLaunch( any(ActivityInterceptorCallback.ActivityInterceptorInfo.class)); @@ -505,7 +538,7 @@ public class ActivityStartInterceptorTest { when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock); Intent intent = new Intent().setPackage(sandboxPackageNameMock); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); verify(spyCallback, times(1)).onInterceptActivityLaunch( any(ActivityInterceptorCallback.ActivityInterceptorInfo.class)); @@ -522,7 +555,7 @@ public class ActivityStartInterceptorTest { when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock); Intent intent = new Intent().setComponent(new ComponentName(sandboxPackageNameMock, "")); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); verify(spyCallback, times(1)).onInterceptActivityLaunch( any(ActivityInterceptorCallback.ActivityInterceptorInfo.class)); @@ -539,23 +572,23 @@ public class ActivityStartInterceptorTest { when(packageManagerMock.getSdkSandboxPackageName()).thenReturn(sandboxPackageNameMock); // Intent: null - mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(null, null, mAInfo, null, null, null, 0, 0, null, null); // Action: null, Package: null, ComponentName: null Intent intent = new Intent(); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); // Wrong Action intent = new Intent().setAction(Intent.ACTION_VIEW); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); // Wrong Package intent = new Intent().setPackage("Random"); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); // Wrong ComponentName's package intent = new Intent().setComponent(new ComponentName("Random", "")); - mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null); + mInterceptor.intercept(intent, null, mAInfo, null, null, null, 0, 0, null, null); verify(spyCallback, never()).onInterceptActivityLaunch( any(ActivityInterceptorCallback.ActivityInterceptorInfo.class)); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index cb92cc5cff67..ae87e38d8faf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -1662,9 +1662,10 @@ public class ActivityStarterTests extends WindowTestsBase { @Test public void testResultCanceledWhenNotAllowedStartingActivity() { + final Task task = new TaskBuilder(mSupervisor).build(); final ActivityStarter starter = prepareStarter(0, false); final ActivityRecord targetRecord = new ActivityBuilder(mAtm).build(); - final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).build(); + final ActivityRecord sourceRecord = new ActivityBuilder(mAtm).setTask(task).build(); targetRecord.resultTo = sourceRecord; // Abort the activity start and ensure the sourceRecord gets the result (RESULT_CANCELED). diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java index c4302db16b98..6b504925281c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -1194,12 +1194,12 @@ public class DisplayRotationTests { } @Test - public void testIsFixedToUserRotation_displayContentOrientationFixed() throws Exception { + public void testIsFixedToUserRotation_displayShouldNotRotateWithContent() throws Exception { mBuilder.build(); - when(mMockDisplayContent.isDisplayOrientationFixed()).thenReturn(true); + when(mMockDisplayContent.shouldRotateWithContent()).thenReturn(false); assertFalse("Display rotation should respect app requested orientation if" - + " the display has fixed orientation.", mTarget.isFixedToUserRotation()); + + " the display does not rotate with content.", mTarget.isFixedToUserRotation()); } @Test @@ -1453,6 +1453,7 @@ public class DisplayRotationTests { .thenReturn(mock(TaskDisplayArea.class)); when(mMockDisplayContent.getWindowConfiguration()) .thenReturn(new WindowConfiguration()); + when(mMockDisplayContent.shouldRotateWithContent()).thenReturn(true); Field field = DisplayContent.class .getDeclaredField("mFixedRotationTransitionListener"); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java index 5dfb901a7c1e..30a89412d946 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java @@ -44,7 +44,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.List; import java.util.Set; /** @@ -106,7 +105,6 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { assertEquals(uidAmount, mDwpc.mRunningUids.size()); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_0_ID) == expectedUid0); assertTrue(mDwpc.mRunningUids.contains(TEST_USER_1_ID) == expectedUid1); - } private ActivityRecord launchActivityOnDisplay(DisplayContent display, int uid) { @@ -197,6 +195,11 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { @Test public void testCanActivityBeLaunched_requiredDisplayCategory() { + doReturn(null).when(mWm.mDisplayManagerInternal) + .getDisplayWindowPolicyController(anyInt()); + mSecondaryDisplay = createNewDisplay(); + assertFalse(mSecondaryDisplay.mDwpcHelper.hasController()); + ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm, mSupervisor, mock(ActivityStartInterceptor.class)); final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build(); @@ -233,20 +236,14 @@ public class DisplayWindowPolicyControllerTests extends WindowTestsBase { public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent, @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, boolean isNewTask) { - return false; + return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask); } @Override - public boolean canContainActivities(@NonNull List<ActivityInfo> activities, - @WindowConfiguration.WindowingMode int windowingMode) { - final int activityCount = activities.size(); - for (int i = 0; i < activityCount; i++) { - final ActivityInfo aInfo = activities.get(i); - if (aInfo.getComponentName().equals(DISALLOWED_ACTIVITY)) { - return false; - } - } - return true; + protected boolean canContainActivity(@NonNull ActivityInfo activity, + @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId, + boolean isNewTask) { + return !activity.getComponentName().equals(DISALLOWED_ACTIVITY); } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java index e1fc0cfdc317..80e169d8d579 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxConfigurationTest.java @@ -250,4 +250,42 @@ public class LetterboxConfigurationTest { times(expectedTime)).setLetterboxPositionForVerticalReachability(halfFoldPose, expected); } + + @Test + public void test_letterboxPositionWhenReachabilityEnabledIsReset() { + // Check that horizontal reachability is set with correct arguments + mLetterboxConfiguration.resetPersistentLetterboxPositionForHorizontalReachability(); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForHorizontalReachability( + false /* forBookMode */, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_CENTER); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForHorizontalReachability( + true /* forBookMode */, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT); + + // Check that vertical reachability is set with correct arguments + mLetterboxConfiguration.resetPersistentLetterboxPositionForVerticalReachability(); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForVerticalReachability( + false /* forTabletopMode */, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForVerticalReachability( + true /* forTabletopMode */, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP); + } + + @Test + public void test_lettterboxPositionWhenReachabilityEnabledIsSet() { + // Check that horizontal reachability is set with correct arguments + mLetterboxConfiguration.setPersistentLetterboxPositionForHorizontalReachability( + false /* forBookMode */, LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForHorizontalReachability( + false /* forBookMode */, + LETTERBOX_HORIZONTAL_REACHABILITY_POSITION_LEFT); + + // Check that vertical reachability is set with correct arguments + mLetterboxConfiguration.setPersistentLetterboxPositionForVerticalReachability( + false /* forTabletopMode */, LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP); + verify(mLetterboxConfigurationPersister).setLetterboxPositionForVerticalReachability( + false /* forTabletopMode */, + LETTERBOX_VERTICAL_REACHABILITY_POSITION_TOP); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index 739737eb318d..07cfbf094e5d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -678,6 +678,39 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase { WINDOWING_MODE_FULLSCREEN); } + @Test + public void testInheritsSourceTaskWindowingModeWhenActivityIsInDifferentWindowingMode() { + final TestDisplayContent fullscreenDisplay = createNewDisplayContent( + WINDOWING_MODE_FULLSCREEN); + final ActivityRecord source = createSourceActivity(fullscreenDisplay); + source.setWindowingMode(WINDOWING_MODE_PINNED); + source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM); + + assertEquals(RESULT_CONTINUE, + new CalculateRequestBuilder().setSource(source).calculate()); + + assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode, + WINDOWING_MODE_FULLSCREEN); + } + + @Test + public void testDoesNotInheritsSourceTaskWindowingModeWhenActivityIsInFreeformWindowingMode() { + // The activity could end up in different windowing mode state after calling finish() + // while the task would still hold the WINDOWING_MODE_PINNED state, or in other words + // be still in the Picture in Picture mode. + final TestDisplayContent fullscreenDisplay = createNewDisplayContent( + WINDOWING_MODE_FULLSCREEN); + final ActivityRecord source = createSourceActivity(fullscreenDisplay); + source.setWindowingMode(WINDOWING_MODE_FREEFORM); + source.getTask().setWindowingMode(WINDOWING_MODE_PINNED); + + assertEquals(RESULT_CONTINUE, + new CalculateRequestBuilder().setSource(source).calculate()); + + assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode, + WINDOWING_MODE_FULLSCREEN); + } + @Test public void testKeepsPictureInPictureLaunchModeInOptions() { diff --git a/startop/apps/ColorChanging/app/build.gradle b/startop/apps/ColorChanging/app/build.gradle index ab955aaf90ee..11b14c04f1b9 100644 --- a/startop/apps/ColorChanging/app/build.gradle +++ b/startop/apps/ColorChanging/app/build.gradle @@ -14,7 +14,7 @@ android { buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt') } } } diff --git a/startop/apps/ColorChanging/app/proguard-rules.pro b/startop/apps/ColorChanging/app/proguard-rules.pro deleted file mode 100644 index f1b424510da5..000000000000 --- a/startop/apps/ColorChanging/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index e51696e58f57..7d9b3790c1b5 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -31,6 +32,7 @@ import android.os.Handler; import android.os.ParcelFileDescriptor; import com.android.internal.telecom.IVideoProvider; +import com.android.server.telecom.flags.Flags; import java.io.IOException; import java.io.InputStreamReader; @@ -720,6 +722,7 @@ public final class Call { * The underlying connection was added as a transactional call via the * {@link TelecomManager#addCall} API. */ + @FlaggedApi(Flags.FLAG_VOIP_APP_ACTIONS_SUPPORT) public static final int PROPERTY_IS_TRANSACTIONAL = 0x00008000; //****************************************************************************************** diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 0bb75d87ffc1..ac8200ad420e 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -9456,6 +9456,19 @@ public class CarrierConfigManager { "carrier_supported_satellite_services_per_provider_bundle"; /** + * This config enables modem to scan satellite PLMNs specified as per + * {@link #KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE} and attach to same + * in case cellular networks are not enabled. This will need specific agreement between + * satellite provider and the carrier before enabling this flag. + * + * The default value is false. + * + * @hide + */ + public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL = + "satellite_attach_supported_bool"; + + /** * Indicating whether DUN APN should be disabled when the device is roaming. In that case, * the default APN (i.e. internet) will be used for tethering. * @@ -10465,6 +10478,7 @@ public class CarrierConfigManager { sDefaults.putPersistableBundle( KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE, PersistableBundle.EMPTY); + sDefaults.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false); sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, ""); sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 69b1d6333596..234ca918a144 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2649,10 +2649,6 @@ public class TelephonyManager { return getCurrentPhoneType(); } - private int getPhoneTypeFromProperty() { - return getPhoneTypeFromProperty(getPhoneId()); - } - /** {@hide} */ @UnsupportedAppUsage private int getPhoneTypeFromProperty(int phoneId) { @@ -2662,10 +2658,6 @@ public class TelephonyManager { return getPhoneTypeFromNetworkType(phoneId); } - private int getPhoneTypeFromNetworkType() { - return getPhoneTypeFromNetworkType(getPhoneId()); - } - /** {@hide} */ private int getPhoneTypeFromNetworkType(int phoneId) { // When the system property CURRENT_ACTIVE_PHONE, has not been set, @@ -11564,16 +11556,6 @@ public class TelephonyManager { } /** - * Set TelephonyProperties.icc_operator_numeric for the default phone. - * - * @hide - */ - public void setSimOperatorNumeric(String numeric) { - int phoneId = getPhoneId(); - setSimOperatorNumericForPhone(phoneId, numeric); - } - - /** * Set TelephonyProperties.icc_operator_numeric for the given phone. * * @hide @@ -11588,16 +11570,6 @@ public class TelephonyManager { } /** - * Set TelephonyProperties.icc_operator_alpha for the default phone. - * - * @hide - */ - public void setSimOperatorName(String name) { - int phoneId = getPhoneId(); - setSimOperatorNameForPhone(phoneId, name); - } - - /** * Set TelephonyProperties.icc_operator_alpha for the given phone. * * @hide @@ -11850,17 +11822,6 @@ public class TelephonyManager { } /** - * Set baseband version for the default phone. - * - * @param version baseband version - * @hide - */ - public void setBasebandVersion(String version) { - int phoneId = getPhoneId(); - setBasebandVersionForPhone(phoneId, version); - } - - /** * Set baseband version by phone id. * * @param phoneId for which baseband version is set @@ -11898,18 +11859,6 @@ public class TelephonyManager { } /** - * Set phone type for the default phone. - * - * @param type phone type - * - * @hide - */ - public void setPhoneType(int type) { - int phoneId = getPhoneId(); - setPhoneType(phoneId, type); - } - - /** * Set phone type by phone id. * * @param phoneId for which phone type is set @@ -11927,19 +11876,6 @@ public class TelephonyManager { } /** - * Get OTASP number schema for the default phone. - * - * @param defaultValue default value - * @return OTA SP number schema - * - * @hide - */ - public String getOtaSpNumberSchema(String defaultValue) { - int phoneId = getPhoneId(); - return getOtaSpNumberSchemaForPhone(phoneId, defaultValue); - } - - /** * Get OTASP number schema by phone id. * * @param phoneId for which OTA SP number schema is get @@ -11959,19 +11895,6 @@ public class TelephonyManager { } /** - * Get SMS receive capable from system property for the default phone. - * - * @param defaultValue default value - * @return SMS receive capable - * - * @hide - */ - public boolean getSmsReceiveCapable(boolean defaultValue) { - int phoneId = getPhoneId(); - return getSmsReceiveCapableForPhone(phoneId, defaultValue); - } - - /** * Get SMS receive capable from system property by phone id. * * @param phoneId for which SMS receive capable is get @@ -11989,19 +11912,6 @@ public class TelephonyManager { } /** - * Get SMS send capable from system property for the default phone. - * - * @param defaultValue default value - * @return SMS send capable - * - * @hide - */ - public boolean getSmsSendCapable(boolean defaultValue) { - int phoneId = getPhoneId(); - return getSmsSendCapableForPhone(phoneId, defaultValue); - } - - /** * Get SMS send capable from system property by phone id. * * @param phoneId for which SMS send capable is get @@ -12065,16 +11975,6 @@ public class TelephonyManager { /** * Set the alphabetic name of current registered operator. - * @param name the alphabetic name of current registered operator. - * @hide - */ - public void setNetworkOperatorName(String name) { - int phoneId = getPhoneId(); - setNetworkOperatorNameForPhone(phoneId, name); - } - - /** - * Set the alphabetic name of current registered operator. * @param phoneId which phone you want to set * @param name the alphabetic name of current registered operator. * @hide @@ -12108,16 +12008,6 @@ public class TelephonyManager { /** * Set the numeric name (MCC+MNC) of current registered operator. - * @param operator the numeric name (MCC+MNC) of current registered operator - * @hide - */ - public void setNetworkOperatorNumeric(String numeric) { - int phoneId = getPhoneId(); - setNetworkOperatorNumericForPhone(phoneId, numeric); - } - - /** - * Set the numeric name (MCC+MNC) of current registered operator. * @param phoneId for which phone type is set * @param operator the numeric name (MCC+MNC) of current registered operator * @hide @@ -12133,16 +12023,6 @@ public class TelephonyManager { /** * Set roaming state of the current network, for GSM purposes. - * @param isRoaming is network in romaing state or not - * @hide - */ - public void setNetworkRoaming(boolean isRoaming) { - int phoneId = getPhoneId(); - setNetworkRoamingForPhone(phoneId, isRoaming); - } - - /** - * Set roaming state of the current network, for GSM purposes. * @param phoneId which phone you want to set * @param isRoaming is network in romaing state or not * @hide @@ -12321,21 +12201,6 @@ public class TelephonyManager { } /** - * TODO delete after SuW migrates to new API. - * @hide - */ - public String getLocaleFromDefaultSim() { - try { - final ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getSimLocaleForSubscriber(getSubId()); - } - } catch (RemoteException ex) { - } - return null; - } - - /** * Exception that may be supplied to the callback provided in {@link #requestModemActivityInfo}. * @hide */ diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java index 9994002a4a37..5f6c14a36d46 100644 --- a/telephony/java/android/telephony/satellite/SatelliteManager.java +++ b/telephony/java/android/telephony/satellite/SatelliteManager.java @@ -44,10 +44,14 @@ import com.android.telephony.Rlog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.time.Duration; +import java.util.Arrays; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc. @@ -79,6 +83,23 @@ public final class SatelliteManager { @Nullable private final Context mContext; /** + * Create a new SatelliteManager object pinned to the given subscription ID. + * This is needed only to handle carrier specific satellite features. + * For eg: requestSatelliteAttachEnabledForCarrier and + * requestIsSatelliteAttachEnabledForCarrier + * + * @return a SatelliteManager that uses the given subId for all satellite activities. + * @throws IllegalArgumentException if the subscription is invalid. + * @hide + */ + public SatelliteManager createForSubscriptionId(int subId) { + if (!SubscriptionManager.isValidSubscriptionId(subId)) { + throw new IllegalArgumentException("Invalid subscription ID"); + } + return new SatelliteManager(mContext, subId); + } + + /** * Create an instance of the SatelliteManager. * * @param context The context the SatelliteManager belongs to. @@ -101,26 +122,26 @@ public final class SatelliteManager { } /** - * Exception from the satellite service containing the {@link SatelliteError} error code. + * Exception from the satellite service containing the {@link SatelliteResult} error code. */ public static class SatelliteException extends Exception { - @SatelliteError private final int mErrorCode; + @SatelliteResult private final int mErrorCode; /** * Create a SatelliteException with a given error code. * - * @param errorCode The {@link SatelliteError}. + * @param errorCode The {@link SatelliteResult}. */ - public SatelliteException(@SatelliteError int errorCode) { + public SatelliteException(@SatelliteResult int errorCode) { mErrorCode = errorCode; } /** * Get the error code returned from the satellite service. * - * @return The {@link SatelliteError}. + * @return The {@link SatelliteResult}. */ - @SatelliteError public int getErrorCode() { + @SatelliteResult public int getErrorCode() { return mErrorCode; } } @@ -185,134 +206,134 @@ public final class SatelliteManager { /** * The request was successfully processed. */ - public static final int SATELLITE_ERROR_NONE = 0; + public static final int SATELLITE_RESULT_SUCCESS = 0; /** * A generic error which should be used only when other specific errors cannot be used. */ - public static final int SATELLITE_ERROR = 1; + public static final int SATELLITE_RESULT_ERROR = 1; /** * Error received from the satellite server. */ - public static final int SATELLITE_SERVER_ERROR = 2; + public static final int SATELLITE_RESULT_SERVER_ERROR = 2; /** * Error received from the vendor service. This generic error code should be used * only when the error cannot be mapped to other specific service error codes. */ - public static final int SATELLITE_SERVICE_ERROR = 3; + public static final int SATELLITE_RESULT_SERVICE_ERROR = 3; /** * Error received from satellite modem. This generic error code should be used only when * the error cannot be mapped to other specific modem error codes. */ - public static final int SATELLITE_MODEM_ERROR = 4; + public static final int SATELLITE_RESULT_MODEM_ERROR = 4; /** * Error received from the satellite network. This generic error code should be used only when * the error cannot be mapped to other specific network error codes. */ - public static final int SATELLITE_NETWORK_ERROR = 5; + public static final int SATELLITE_RESULT_NETWORK_ERROR = 5; /** * Telephony is not in a valid state to receive requests from clients. */ - public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6; + public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6; /** * Satellite modem is not in a valid state to receive requests from clients. */ - public static final int SATELLITE_INVALID_MODEM_STATE = 7; + public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7; /** * Either vendor service, or modem, or Telephony framework has received a request with * invalid arguments from its clients. */ - public static final int SATELLITE_INVALID_ARGUMENTS = 8; + public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8; /** * Telephony framework failed to send a request or receive a response from the vendor service * or satellite modem due to internal error. */ - public static final int SATELLITE_REQUEST_FAILED = 9; + public static final int SATELLITE_RESULT_REQUEST_FAILED = 9; /** * Radio did not start or is resetting. */ - public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10; + public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10; /** * The request is not supported by either the satellite modem or the network. */ - public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11; + public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11; /** * Satellite modem or network has no resources available to handle requests from clients. */ - public static final int SATELLITE_NO_RESOURCES = 12; + public static final int SATELLITE_RESULT_NO_RESOURCES = 12; /** * Satellite service is not provisioned yet. */ - public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13; + public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13; /** * Satellite service provision is already in progress. */ - public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14; + public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14; /** * The ongoing request was aborted by either the satellite modem or the network. * This error is also returned when framework decides to abort current send request as one * of the previous send request failed. */ - public static final int SATELLITE_REQUEST_ABORTED = 15; + public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15; /** * The device/subscriber is barred from accessing the satellite service. */ - public static final int SATELLITE_ACCESS_BARRED = 16; + public static final int SATELLITE_RESULT_ACCESS_BARRED = 16; /** * Satellite modem timeout to receive ACK or response from the satellite network after * sending a request to the network. */ - public static final int SATELLITE_NETWORK_TIMEOUT = 17; + public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17; /** * Satellite network is not reachable from the modem. */ - public static final int SATELLITE_NOT_REACHABLE = 18; + public static final int SATELLITE_RESULT_NOT_REACHABLE = 18; /** * The device/subscriber is not authorized to register with the satellite service provider. */ - public static final int SATELLITE_NOT_AUTHORIZED = 19; + public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19; /** * The device does not support satellite. */ - public static final int SATELLITE_NOT_SUPPORTED = 20; + public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20; /** * The current request is already in-progress. */ - public static final int SATELLITE_REQUEST_IN_PROGRESS = 21; + public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21; /** * Satellite modem is currently busy due to which current request cannot be processed. */ - public static final int SATELLITE_MODEM_BUSY = 22; + public static final int SATELLITE_RESULT_MODEM_BUSY = 22; /** @hide */ - @IntDef(prefix = {"SATELLITE_"}, value = { - SATELLITE_ERROR_NONE, - SATELLITE_ERROR, - SATELLITE_SERVER_ERROR, - SATELLITE_SERVICE_ERROR, - SATELLITE_MODEM_ERROR, - SATELLITE_NETWORK_ERROR, - SATELLITE_INVALID_TELEPHONY_STATE, - SATELLITE_INVALID_MODEM_STATE, - SATELLITE_INVALID_ARGUMENTS, - SATELLITE_REQUEST_FAILED, - SATELLITE_RADIO_NOT_AVAILABLE, - SATELLITE_REQUEST_NOT_SUPPORTED, - SATELLITE_NO_RESOURCES, - SATELLITE_SERVICE_NOT_PROVISIONED, - SATELLITE_SERVICE_PROVISION_IN_PROGRESS, - SATELLITE_REQUEST_ABORTED, - SATELLITE_ACCESS_BARRED, - SATELLITE_NETWORK_TIMEOUT, - SATELLITE_NOT_REACHABLE, - SATELLITE_NOT_AUTHORIZED, - SATELLITE_NOT_SUPPORTED, - SATELLITE_REQUEST_IN_PROGRESS, - SATELLITE_MODEM_BUSY + @IntDef(prefix = {"SATELLITE_RESULT_"}, value = { + SATELLITE_RESULT_SUCCESS, + SATELLITE_RESULT_ERROR, + SATELLITE_RESULT_SERVER_ERROR, + SATELLITE_RESULT_SERVICE_ERROR, + SATELLITE_RESULT_MODEM_ERROR, + SATELLITE_RESULT_NETWORK_ERROR, + SATELLITE_RESULT_INVALID_TELEPHONY_STATE, + SATELLITE_RESULT_INVALID_MODEM_STATE, + SATELLITE_RESULT_INVALID_ARGUMENTS, + SATELLITE_RESULT_REQUEST_FAILED, + SATELLITE_RESULT_RADIO_NOT_AVAILABLE, + SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, + SATELLITE_RESULT_NO_RESOURCES, + SATELLITE_RESULT_SERVICE_NOT_PROVISIONED, + SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS, + SATELLITE_RESULT_REQUEST_ABORTED, + SATELLITE_RESULT_ACCESS_BARRED, + SATELLITE_RESULT_NETWORK_TIMEOUT, + SATELLITE_RESULT_NOT_REACHABLE, + SATELLITE_RESULT_NOT_AUTHORIZED, + SATELLITE_RESULT_NOT_SUPPORTED, + SATELLITE_RESULT_REQUEST_IN_PROGRESS, + SATELLITE_RESULT_MODEM_BUSY }) @Retention(RetentionPolicy.SOURCE) - public @interface SatelliteError {} + public @interface SatelliteResult {} /** * Unknown Non-Terrestrial radio technology. This generic radio technology should be used @@ -403,7 +424,7 @@ public final class SatelliteManager { * {@code false} to disable. * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable. * @param executor The executor on which the error code listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -412,7 +433,7 @@ public final class SatelliteManager { public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -446,7 +467,7 @@ public final class SatelliteManager { * will return a {@code boolean} with value {@code true} if the satellite modem * is enabled and {@code false} otherwise. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -464,7 +485,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_ENABLED)) { boolean isSatelliteEnabled = resultData.getBoolean(KEY_SATELLITE_ENABLED); @@ -473,8 +494,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_ENABLED does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -501,7 +522,7 @@ public final class SatelliteManager { * will return a {@code boolean} with value {@code true} if demo mode is enabled * and {@code false} otherwise. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -519,7 +540,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_DEMO_MODE_ENABLED)) { boolean isDemoModeEnabled = resultData.getBoolean(KEY_DEMO_MODE_ENABLED); @@ -528,8 +549,8 @@ public final class SatelliteManager { } else { loge("KEY_DEMO_MODE_ENABLED does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -556,7 +577,7 @@ public final class SatelliteManager { * will return a {@code boolean} with value {@code true} if the satellite * service is supported on the device and {@code false} otherwise. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws IllegalStateException if the Telephony process is not currently available. */ @@ -572,7 +593,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) { boolean isSatelliteSupported = resultData.getBoolean(KEY_SATELLITE_SUPPORTED); @@ -581,8 +602,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_SUPPORTED does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -608,7 +629,7 @@ public final class SatelliteManager { * If the request is successful, {@link OutcomeReceiver#onResult(Object)} * will return the {@link SatelliteCapabilities} of the satellite service. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -626,7 +647,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_CAPABILITIES)) { SatelliteCapabilities capabilities = resultData.getParcelable(KEY_SATELLITE_CAPABILITIES, @@ -636,8 +657,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_CAPABILITIES does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -791,16 +812,37 @@ public final class SatelliteManager { public @interface DatagramType {} /** + * Satellite communication restricted by user. + * @hide + */ + public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER = 0; + + /** + * Satellite communication restricted by geolocation. This can be + * triggered based upon geofence input provided by carrier to enable or disable satellite. + * @hide + */ + public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1; + + /** @hide */ + @IntDef(prefix = "SATELLITE_COMMUNICATION_RESTRICTION_REASON_", value = { + SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, + SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SatelliteCommunicationRestrictionReason {} + + /** * Start receiving satellite transmission updates. * This can be called by the pointing UI when the user starts pointing to the satellite. * Modem should continue to report the pointing input as the device or satellite moves. - * Satellite transmission updates are started only on {@link #SATELLITE_ERROR_NONE}. + * Satellite transmission updates are started only on {@link #SATELLITE_RESULT_SUCCESS}. * All other results indicate that this operation failed. * Once satellite transmission updates begin, position and datagram transfer state updates * will be sent through {@link SatelliteTransmissionUpdateCallback}. * * @param executor The executor on which the callback and error code listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * @param callback The callback to notify of satellite transmission updates. * * @throws SecurityException if the caller doesn't have required permission. @@ -809,7 +851,7 @@ public final class SatelliteManager { @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) public void startSatelliteTransmissionUpdates(@NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener, + @SatelliteResult @NonNull Consumer<Integer> resultListener, @NonNull SatelliteTransmissionUpdateCallback callback) { Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -866,12 +908,12 @@ public final class SatelliteManager { * Stop receiving satellite transmission updates. * This can be called by the pointing UI when the user stops pointing to the satellite. * Satellite transmission updates are stopped and the callback is unregistered only on - * {@link #SATELLITE_ERROR_NONE}. All other results that this operation failed. + * {@link #SATELLITE_RESULT_SUCCESS}. All other results that this operation failed. * * @param callback The callback that was passed to {@link * #startSatelliteTransmissionUpdates(Executor, Consumer, SatelliteTransmissionUpdateCallback)}. * @param executor The executor on which the error code listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -881,7 +923,7 @@ public final class SatelliteManager { public void stopSatelliteTransmissionUpdates( @NonNull SatelliteTransmissionUpdateCallback callback, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(callback); Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -905,7 +947,7 @@ public final class SatelliteManager { } else { loge("stopSatelliteTransmissionUpdates: No internal callback."); executor.execute(() -> Binder.withCleanCallingIdentity( - () -> resultListener.accept(SATELLITE_INVALID_ARGUMENTS))); + () -> resultListener.accept(SATELLITE_RESULT_INVALID_ARGUMENTS))); } } else { throw new IllegalStateException("telephony service is null."); @@ -927,7 +969,7 @@ public final class SatelliteManager { * request. Even when the cancellation is signaled, Telephony will * still trigger the callback to return the result of this request. * @param executor The executor on which the error code listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -937,7 +979,7 @@ public final class SatelliteManager { public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(token); Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -980,7 +1022,7 @@ public final class SatelliteManager { * This should match with the token passed as input in * {@link #provisionSatelliteService(String, byte[], CancellationSignal, Executor, * Consumer)} - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -989,7 +1031,7 @@ public final class SatelliteManager { public void deprovisionSatelliteService(@NonNull String token, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(token); Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -1020,14 +1062,14 @@ public final class SatelliteManager { * @param executor The executor on which the callback will be called. * @param callback The callback to handle the satellite provision state changed event. * - * @return The {@link SatelliteError} result of the operation. + * @return The {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. */ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) - @SatelliteError public int registerForSatelliteProvisionStateChanged( + @SatelliteResult public int registerForSatelliteProvisionStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteProvisionStateCallback callback) { Objects.requireNonNull(executor); @@ -1055,7 +1097,7 @@ public final class SatelliteManager { loge("registerForSatelliteProvisionStateChanged() RemoteException: " + ex); ex.rethrowFromSystemServer(); } - return SATELLITE_REQUEST_FAILED; + return SATELLITE_RESULT_REQUEST_FAILED; } /** @@ -1102,7 +1144,7 @@ public final class SatelliteManager { * will return a {@code boolean} with value {@code true} if the device is * provisioned with a satellite provider and {@code false} otherwise. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -1120,7 +1162,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) { boolean isSatelliteProvisioned = resultData.getBoolean(KEY_SATELLITE_PROVISIONED); @@ -1129,8 +1171,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_PROVISIONED does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -1154,14 +1196,14 @@ public final class SatelliteManager { * @param executor The executor on which the callback will be called. * @param callback The callback to handle the satellite modem state changed event. * - * @return The {@link SatelliteError} result of the operation. + * @return The {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. */ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) - @SatelliteError public int registerForSatelliteModemStateChanged( + @SatelliteResult public int registerForSatelliteModemStateChanged( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteStateCallback callback) { Objects.requireNonNull(executor); @@ -1186,7 +1228,7 @@ public final class SatelliteManager { loge("registerForSatelliteModemStateChanged() RemoteException:" + ex); ex.rethrowFromSystemServer(); } - return SATELLITE_REQUEST_FAILED; + return SATELLITE_RESULT_REQUEST_FAILED; } /** @@ -1232,14 +1274,14 @@ public final class SatelliteManager { * @param callback The callback to handle incoming datagrams over satellite. * This callback with be invoked when a new datagram is received from satellite. * - * @return The {@link SatelliteError} result of the operation. + * @return The {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. */ @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) - @SatelliteError public int registerForSatelliteDatagram( + @SatelliteResult public int registerForSatelliteDatagram( @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteDatagramCallback callback) { Objects.requireNonNull(executor); @@ -1280,7 +1322,7 @@ public final class SatelliteManager { loge("registerForSatelliteDatagram() RemoteException:" + ex); ex.rethrowFromSystemServer(); } - return SATELLITE_REQUEST_FAILED; + return SATELLITE_RESULT_REQUEST_FAILED; } /** @@ -1327,7 +1369,7 @@ public final class SatelliteManager { * Consumer)} )} * * @param executor The executor on which the result listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -1335,7 +1377,7 @@ public final class SatelliteManager { @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) public void pollPendingSatelliteDatagrams(@NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -1380,7 +1422,7 @@ public final class SatelliteManager { * user activity and the application's ability to determine the * best possible UX experience for the user. * @param executor The executor on which the result listener will be called. - * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * @param resultListener Listener for the {@link SatelliteResult} result of the operation. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -1390,7 +1432,7 @@ public final class SatelliteManager { public void sendSatelliteDatagram(@DatagramType int datagramType, @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI, @NonNull @CallbackExecutor Executor executor, - @SatelliteError @NonNull Consumer<Integer> resultListener) { + @SatelliteResult @NonNull Consumer<Integer> resultListener) { Objects.requireNonNull(datagram); Objects.requireNonNull(executor); Objects.requireNonNull(resultListener); @@ -1426,7 +1468,7 @@ public final class SatelliteManager { * communication is allowed for the current location and * {@code false} otherwise. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -1445,7 +1487,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) { boolean isSatelliteCommunicationAllowed = resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED); @@ -1454,8 +1496,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -1484,7 +1526,7 @@ public final class SatelliteManager { * If the request is successful, {@link OutcomeReceiver#onResult(Object)} * will return the time after which the satellite will be visible. * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} - * will return a {@link SatelliteException} with the {@link SatelliteError}. + * will return a {@link SatelliteException} with the {@link SatelliteResult}. * * @throws SecurityException if the caller doesn't have required permission. * @throws IllegalStateException if the Telephony process is not currently available. @@ -1502,7 +1544,7 @@ public final class SatelliteManager { ResultReceiver receiver = new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { - if (resultCode == SATELLITE_ERROR_NONE) { + if (resultCode == SATELLITE_RESULT_SUCCESS) { if (resultData.containsKey(KEY_SATELLITE_NEXT_VISIBILITY)) { int nextVisibilityDuration = resultData.getInt(KEY_SATELLITE_NEXT_VISIBILITY); @@ -1512,8 +1554,8 @@ public final class SatelliteManager { } else { loge("KEY_SATELLITE_NEXT_VISIBILITY does not exist."); executor.execute(() -> Binder.withCleanCallingIdentity(() -> - callback.onError( - new SatelliteException(SATELLITE_REQUEST_FAILED)))); + callback.onError(new SatelliteException( + SATELLITE_RESULT_REQUEST_FAILED)))); } } else { executor.execute(() -> Binder.withCleanCallingIdentity(() -> @@ -1559,6 +1601,182 @@ public final class SatelliteManager { } } + /** + * User request to enable or disable carrier supported satellite plmn scan and attach by modem. + * <p> + * This API should be called by only settings app to pass down the user input for + * enabling/disabling satellite. This user input will be persisted across device reboots. + * <p> + * Satellite will be enabled only when the following conditions are met: + * <ul> + * <li>Users want to enable it.</li> + * <li>There is no satellite communication restriction, which is added by + * {@link #addSatelliteAttachRestrictionForCarrier(int, Executor, Consumer)}</li> + * <li>The carrier config {@link + * android.telephony.CarrierConfigManager#KEY_SATELLITE_ATTACH_SUPPORTED_BOOL} is set to + * {@code true}.</li> + * </ul> + * + * @param enableSatellite {@code true} to enable the satellite and {@code false} to disable. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) + public void requestSatelliteAttachEnabledForCarrier(boolean enableSatellite, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + Objects.requireNonNull(executor); + Objects.requireNonNull(resultListener); + + if (enableSatellite) { + removeSatelliteAttachRestrictionForCarrier( + SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, executor, resultListener); + } else { + addSatelliteAttachRestrictionForCarrier( + SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER, executor, resultListener); + } + } + + /** + * Request to get whether the carrier supported satellite plmn scan and attach by modem is + * enabled by user. + * + * @param executor The executor on which the callback will be called. + * @param callback The callback object to which the result will be delivered. + * If the request is successful, {@link OutcomeReceiver#onResult(Object)} + * will return a {@code boolean} with value {@code true} if the satellite + * is enabled and {@code false} otherwise. + * If the request is not successful, {@link OutcomeReceiver#onError(Throwable)} + * will return a {@link SatelliteException} with the {@link SatelliteError}. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) + public void requestIsSatelliteAttachEnabledForCarrier( + @NonNull @CallbackExecutor Executor executor, + @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) { + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); + + Set<Integer> restrictionReason = getSatelliteAttachRestrictionReasonsForCarrier(); + executor.execute(() -> callback.onResult( + !restrictionReason.contains(SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER))); + } + + /** + * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach + * by modem. + * + * @param reason Reason for disallowing satellite communication. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) + public void addSatelliteAttachRestrictionForCarrier( + @SatelliteCommunicationRestrictionReason int reason, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> Binder.withCleanCallingIdentity( + () -> resultListener.accept(result))); + } + }; + telephony.addSatelliteAttachRestrictionForCarrier(mSubId, reason, errorCallback); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + loge("addSatelliteAttachRestrictionForCarrier() RemoteException:" + ex); + ex.rethrowFromSystemServer(); + } + } + + /** + * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach + * by modem. + * + * @param reason Reason for disallowing satellite communication. + * @param executor The executor on which the error code listener will be called. + * @param resultListener Listener for the {@link SatelliteError} result of the operation. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) + public void removeSatelliteAttachRestrictionForCarrier( + @SatelliteCommunicationRestrictionReason int reason, + @NonNull @CallbackExecutor Executor executor, + @SatelliteResult @NonNull Consumer<Integer> resultListener) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> Binder.withCleanCallingIdentity( + () -> resultListener.accept(result))); + } + }; + telephony.removeSatelliteAttachRestrictionForCarrier(mSubId, reason, errorCallback); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + loge("removeSatelliteAttachRestrictionForCarrier() RemoteException:" + ex); + ex.rethrowFromSystemServer(); + } + } + + /** + * Get reasons for disallowing satellite attach, as requested by + * {@link #addSatelliteAttachRestrictionForCarrier(int, Executor, Consumer)} + * + * @return Set of reasons for disallowing satellite communication. + * + * @throws SecurityException if the caller doesn't have required permission. + * @throws IllegalStateException if the Telephony process is not currently available. + * @hide + */ + @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION) + @SatelliteCommunicationRestrictionReason + public @NonNull Set<Integer> getSatelliteAttachRestrictionReasonsForCarrier() { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + int[] receivedArray = + telephony.getSatelliteAttachRestrictionReasonsForCarrier(mSubId); + if (receivedArray.length == 0) { + logd("received set is empty, create empty set"); + return new HashSet<>(); + } else { + return Arrays.stream(receivedArray).boxed().collect(Collectors.toSet()); + } + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + loge("getSatelliteAttachRestrictionReasonsForCarrier() RemoteException: " + ex); + ex.rethrowFromSystemServer(); + } + return null; + } + private static ITelephony getITelephony() { ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer .getTelephonyServiceManager() diff --git a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java index d7d892a7c30a..7ac06b04a8eb 100644 --- a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java +++ b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java @@ -43,7 +43,7 @@ public interface SatelliteTransmissionUpdateCallback { */ void onSendDatagramStateChanged( @SatelliteManager.SatelliteDatagramTransferState int state, int sendPendingCount, - @SatelliteManager.SatelliteError int errorCode); + @SatelliteManager.SatelliteResult int errorCode); /** * Called when satellite datagram receive state changed. @@ -54,5 +54,5 @@ public interface SatelliteTransmissionUpdateCallback { */ void onReceiveDatagramStateChanged( @SatelliteManager.SatelliteDatagramTransferState int state, int receivePendingCount, - @SatelliteManager.SatelliteError int errorCode); + @SatelliteManager.SatelliteResult int errorCode); } diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl index ea4e2e2ef1b9..02661de34fb2 100644 --- a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl +++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl @@ -382,4 +382,64 @@ oneway interface ISatellite { */ void requestTimeForNextSatelliteVisibility(in IIntegerConsumer resultCallback, in IIntegerConsumer callback); + + /** + * Set the non-terrestrial PLMN with lower priority than terrestrial networks. + * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on + * SIM profile. Acquisition of satellite based system is lower priority to terrestrial + * networks. UE shall make all attempts to acquire terrestrial service prior to camping on + * satellite LTE service. + * + * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use + * this information to determine the relevant carrier. + * @param plmnList The list of roaming PLMN used for connecting to satellite networks. + * @param resultCallback The callback to receive the error code result of the operation. + * + * Valid error codes returned: + * SatelliteError:NONE + * SatelliteError:INVALID_ARGUMENTS + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:NO_RESOURCES + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + void setSatellitePlmn(int simSlot, in List<String> plmnList, + in IIntegerConsumer resultCallback); + + /** + * Enable or disable satellite in the cellular modem associated with a carrier. + * Refer setSatellitePlmn for the details of satellite PLMN scanning process. + * + * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use + * this information to determine the relevant carrier. + * @param serial Serial number of request. + * @param enable {@code true} to enable satellite, {@code false} to disable satellite. + * + * Valid errors returned: + * SatelliteError:NONE + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + void setSatelliteEnabledForCarrier(int simSlot, boolean satelliteEnabled, + in IIntegerConsumer callback); + + /** + * Check whether satellite is enabled in the cellular modem associated with a carrier. + * + * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use + * this information to determine the relevant carrier. + * @param serial Serial number of request. + * + * Valid errors returned: + * SatelliteError:NONE + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + void requestIsSatelliteEnabledForCarrier(int simSlot, in IIntegerConsumer resultCallback, + in IBooleanConsumer callback); } diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl index 5e692151c604..d68716291b8e 100644 --- a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl +++ b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl @@ -19,7 +19,6 @@ package android.telephony.satellite.stub; import android.telephony.satellite.stub.NTRadioTechnology; import android.telephony.satellite.stub.PointingInfo; import android.telephony.satellite.stub.SatelliteDatagram; -import android.telephony.satellite.stub.SatelliteError; import android.telephony.satellite.stub.SatelliteModemState; /** diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java index 17d026cc8c1c..6451daf2e752 100644 --- a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java +++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java @@ -25,6 +25,7 @@ import com.android.internal.telephony.IBooleanConsumer; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.util.TelephonyUtils; +import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -212,6 +213,34 @@ public class SatelliteImplBase extends SatelliteService { "requestTimeForNextSatelliteVisibility"); } + @Override + public void setSatellitePlmn(int simSlot, List<String> plmnList, + IIntegerConsumer errorCallback) + throws RemoteException { + executeMethodAsync( + () -> SatelliteImplBase.this + .setSatellitePlmn(simSlot, plmnList, errorCallback), + "setSatellitePlmn"); + } + + @Override + public void setSatelliteEnabledForCarrier(int simSlot, boolean enableSatellite, + IIntegerConsumer errorCallback) throws RemoteException { + executeMethodAsync( + () -> SatelliteImplBase.this + .setSatelliteEnabledForCarrier(simSlot, enableSatellite, errorCallback), + "setSatelliteEnabledForCarrier"); + } + + @Override + public void requestIsSatelliteEnabledForCarrier(int simSlot, IIntegerConsumer errorCallback, + IBooleanConsumer callback) throws RemoteException { + executeMethodAsync( + () -> SatelliteImplBase.this + .requestIsSatelliteEnabledForCarrier(simSlot, errorCallback, callback), + "requestIsSatelliteEnabledForCarrier"); + } + // Call the methods with a clean calling identity on the executor and wait indefinitely for // the future to return. private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException { @@ -618,4 +647,75 @@ public class SatelliteImplBase extends SatelliteService { @NonNull IIntegerConsumer callback) { // stub implementation } + + + /** + * Set the non-terrestrial PLMN with lower priority than terrestrial networks. + * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on + * SIM profile. Acquisition of satellite based system is lower priority to terrestrial + * networks. UE shall make all attempts to acquire terrestrial service prior to camping on + * satellite LTE service. + * This method must only take effect if {@link #setSatelliteEnabledForCarrier} is {@code true}, + * and return an error otherwise. + * + * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be + * applied. The modem will use this information to determine the relevant carrier. + * @param errorCallback The callback to receive the error code result of the operation. + * @param plmnList The list of roaming PLMN used for connecting to satellite networks. + * + * Valid error codes returned: + * SatelliteError:NONE + * SatelliteError:INVALID_ARGUMENTS + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:NO_RESOURCES + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + public void setSatellitePlmn(@NonNull int simLogicalSlotIndex, @NonNull List<String> plmnList, + @NonNull IIntegerConsumer errorCallback) { + // stub implementation + } + + /** + * Request to enable or disable carrier supported satellite plmn scan and attach by modem. + * Refer {@link #setSatellitePlmn} for the details of satellite PLMN scanning process. + * + * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be + * applied. The modem will use this information to determine the relevant carrier. + * @param satelliteEnabled {@code true} to enable satellite, {@code false} to disable satellite. + * @param callback {@code true} to enable satellite, {@code false} to disable satellite. + * + * Valid errors returned: + * SatelliteError:NONE + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + public void setSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex, + @NonNull boolean satelliteEnabled, @NonNull IIntegerConsumer callback) { + // stub implementation + } + + /** + * Request to get whether the satellite is enabled in the cellular modem associated with a + * carrier. + * + * @param simLogicalSlotIndex Indicates the SIM logical slot index to which this API will be + * applied. The modem will use this information to determine the relevant carrier. + * @param errorCallback The callback to receive the error code result of the operation. + * @param callback {@code true} to satellite enabled, {@code false} to satellite disabled. + * + * Valid errors returned: + * SatelliteError:NONE + * SatelliteError:INVALID_MODEM_STATE + * SatelliteError:MODEM_ERR + * SatelliteError:RADIO_NOT_AVAILABLE + * SatelliteError:REQUEST_NOT_SUPPORTED + */ + public void requestIsSatelliteEnabledForCarrier(@NonNull int simLogicalSlotIndex, + @NonNull IIntegerConsumer errorCallback, @NonNull IBooleanConsumer callback) { + // stub implementation + } } diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteResult.aidl index 6a110a90276f..639b4831cb16 100644 --- a/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl +++ b/telephony/java/android/telephony/satellite/stub/SatelliteResult.aidl @@ -20,91 +20,87 @@ package android.telephony.satellite.stub; * {@hide} */ @Backing(type="int") -enum SatelliteError { +enum SatelliteResult { /** * The request was successfully processed. */ - ERROR_NONE = 0, + SATELLITE_RESULT_SUCCESS = 0, /** * A generic error which should be used only when other specific errors cannot be used. */ - SATELLITE_ERROR = 1, + SATELLITE_RESULT_ERROR = 1, /** * Error received from the satellite server. */ - SERVER_ERROR = 2, + SATELLITE_RESULT_SERVER_ERROR = 2, /** * Error received from the vendor service. This generic error code should be used * only when the error cannot be mapped to other specific service error codes. */ - SERVICE_ERROR = 3, + SATELLITE_RESULT_SERVICE_ERROR = 3, /** * Error received from satellite modem. This generic error code should be used only when * the error cannot be mapped to other specific modem error codes. */ - MODEM_ERROR = 4, + SATELLITE_RESULT_MODEM_ERROR = 4, /** * Error received from the satellite network. This generic error code should be used only when * the error cannot be mapped to other specific network error codes. */ - NETWORK_ERROR = 5, - /** - * Telephony is not in a valid state to receive requests from clients. - */ - INVALID_TELEPHONY_STATE = 6, + SATELLITE_RESULT_NETWORK_ERROR = 5, /** * Satellite modem is not in a valid state to receive requests from clients. */ - INVALID_MODEM_STATE = 7, + SATELLITE_RESULT_INVALID_MODEM_STATE = 6, /** * Either vendor service, or modem, or Telephony framework has received a request with * invalid arguments from its clients. */ - INVALID_ARGUMENTS = 8, + SATELLITE_RESULT_INVALID_ARGUMENTS = 7, /** * Telephony framework failed to send a request or receive a response from the vendor service * or satellite modem due to internal error. */ - REQUEST_FAILED = 9, + SATELLITE_RESULT_REQUEST_FAILED = 8, /** * Radio did not start or is resetting. */ - RADIO_NOT_AVAILABLE = 10, + SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 9, /** * The request is not supported by either the satellite modem or the network. */ - REQUEST_NOT_SUPPORTED = 11, + SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 10, /** * Satellite modem or network has no resources available to handle requests from clients. */ - NO_RESOURCES = 12, + SATELLITE_RESULT_NO_RESOURCES = 11, /** * Satellite service is not provisioned yet. */ - SERVICE_NOT_PROVISIONED = 13, + SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 12, /** * Satellite service provision is already in progress. */ - SERVICE_PROVISION_IN_PROGRESS = 14, + SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 13, /** * The ongoing request was aborted by either the satellite modem or the network. */ - REQUEST_ABORTED = 15, + SATELLITE_RESULT_REQUEST_ABORTED = 14, /** * The device/subscriber is barred from accessing the satellite service. */ - SATELLITE_ACCESS_BARRED = 16, + SATELLITE_RESULT_ACCESS_BARRED = 15, /** * Satellite modem timeout to receive ACK or response from the satellite network after * sending a request to the network. */ - NETWORK_TIMEOUT = 17, + SATELLITE_RESULT_NETWORK_TIMEOUT = 16, /** * Satellite network is not reachable from the modem. */ - SATELLITE_NOT_REACHABLE = 18, + SATELLITE_RESULT_NOT_REACHABLE = 17, /** * The device/subscriber is not authorized to register with the satellite service provider. */ - NOT_AUTHORIZED = 19 + SATELLITE_RESULT_NOT_AUTHORIZED = 18 } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 06071feccf69..3aa5a5a14bc8 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -3033,4 +3033,42 @@ interface ITelephony { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + "android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)") List<String> getShaIdFromAllowList(String pkgName, int carrierId); + + /** + * Add a restriction reason for disallowing satellite communication. + * + * @param subId The subId of the subscription to request for. + * @param reason Reason for disallowing satellite communication for carrier. + * @param callback Listener for the {@link SatelliteManager.SatelliteError} result of the + * operation. + */ + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + + "android.Manifest.permission.SATELLITE_COMMUNICATION)") + void addSatelliteAttachRestrictionForCarrier(int subId, int reason, + in IIntegerConsumer callback); + + /** + * Remove a restriction reason for disallowing satellite communication. + * + * @param subId The subId of the subscription to request for. + * @param reason Reason for disallowing satellite communication. + * @param callback Listener for the {@link SatelliteManager.SatelliteError} result of the + * operation. + */ + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + + "android.Manifest.permission.SATELLITE_COMMUNICATION)") + void removeSatelliteAttachRestrictionForCarrier(int subId, int reason, + in IIntegerConsumer callback); + + /** + * Get reasons for disallowing satellite communication, as requested by + * {@link #addSatelliteAttachRestrictionForCarrier(int, int)}. + * + * @param subId The subId of the subscription to request for. + * + * @return Set of reasons for disallowing satellite communication. + */ + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(" + + "android.Manifest.permission.SATELLITE_COMMUNICATION)") + int[] getSatelliteAttachRestrictionReasonsForCarrier(int subId); } diff --git a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml b/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml deleted file mode 100644 index 3f1a4f3a26a1..000000000000 --- a/tests/ApkVerityTest/ApkVerityTestApp/feature_split/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (C) 2019 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. - --> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.apkverity" - android:isFeatureSplit="true" - split="feature_x"> - <application> - <activity android:name=".feature_x.DummyActivity"/> - </application> -</manifest> diff --git a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java b/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java deleted file mode 100644 index 482f633e2fe1..000000000000 --- a/tests/ApkVerityTest/src/com/android/apkverity/ApkVerityTest.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2019 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.apkverity; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.platform.test.annotations.RootPermissionTest; - -import com.android.blockdevicewriter.BlockDeviceWriter; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.ITestDevice; -import com.android.tradefed.log.LogUtil.CLog; -import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; -import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; -import com.android.tradefed.util.CommandResult; -import com.android.tradefed.util.CommandStatus; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * This test makes sure app installs with fs-verity signature, and on-access verification works. - * - * <p>When an app is installed, all or none of the files should have their corresponding .fsv_sig - * signature file. Otherwise, install will fail. - * - * <p>Once installed, file protected by fs-verity is verified by kernel every time a block is loaded - * from disk to memory. The file is immutable by design, enforced by filesystem. - * - * <p>In order to make sure a block of the file is readable only if the underlying block on disk - * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical - * address against the block device. - * - * <p>Requirements to run this test: - * <ul> - * <li>Device is rootable</li> - * <li>The filesystem supports fs-verity</li> - * <li>The feature flag is enabled</li> - * </ul> - */ -@RootPermissionTest -@RunWith(DeviceJUnit4ClassRunner.class) -public class ApkVerityTest extends BaseHostJUnit4Test { - private static final String TARGET_PACKAGE = "com.android.apkverity"; - - private static final String BASE_APK = "ApkVerityTestApp.apk"; - private static final String BASE_APK_DM = "ApkVerityTestApp.dm"; - private static final String SPLIT_APK = "ApkVerityTestAppSplit.apk"; - private static final String SPLIT_APK_DM = "ApkVerityTestAppSplit.dm"; - - private static final String INSTALLED_BASE_APK = "base.apk"; - private static final String INSTALLED_BASE_DM = "base.dm"; - private static final String INSTALLED_SPLIT_APK = "split_feature_x.apk"; - private static final String INSTALLED_SPLIT_DM = "split_feature_x.dm"; - private static final String INSTALLED_BASE_APK_FSV_SIG = "base.apk.fsv_sig"; - private static final String INSTALLED_BASE_DM_FSV_SIG = "base.dm.fsv_sig"; - private static final String INSTALLED_SPLIT_APK_FSV_SIG = "split_feature_x.apk.fsv_sig"; - private static final String INSTALLED_SPLIT_DM_FSV_SIG = "split_feature_x.dm.fsv_sig"; - - private static final String DAMAGING_EXECUTABLE = "/data/local/tmp/block_device_writer"; - private static final String CERT_PATH = "/data/local/tmp/ApkVerityTestCert.der"; - - /** Only 4K page is supported by fs-verity currently. */ - private static final int FSVERITY_PAGE_SIZE = 4096; - - private ITestDevice mDevice; - private boolean mDmRequireFsVerity; - - @Before - public void setUp() throws DeviceNotAvailableException { - mDevice = getDevice(); - mDmRequireFsVerity = "true".equals( - mDevice.getProperty("pm.dexopt.dm.require_fsverity")); - - expectRemoteCommandToSucceed("cmd file_integrity append-cert " + CERT_PATH); - uninstallPackage(TARGET_PACKAGE); - } - - @After - public void tearDown() throws DeviceNotAvailableException { - expectRemoteCommandToSucceed("cmd file_integrity remove-last-cert"); - uninstallPackage(TARGET_PACKAGE); - } - - @Test - public void testFsverityKernelSupports() throws DeviceNotAvailableException { - ITestDevice.MountPointInfo mountPoint = mDevice.getMountPointInfo("/data"); - expectRemoteCommandToSucceed("test -f /sys/fs/" + mountPoint.type + "/features/verity"); - } - - @Test - public void testInstallBase() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity(INSTALLED_BASE_APK); - } - - @Test - public void testInstallBaseWithWrongSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFile(SPLIT_APK_DM + ".fsv_sig", - BASE_APK + ".fsv_sig") - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithSplit() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(SPLIT_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK); - } - - @Test - public void testInstallBaseWithDm() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM); - } - - @Test - public void testInstallEverything() throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFileAndSignature(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM); - } - - @Test - public void testInstallSplitOnly() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFileAndSignature(SPLIT_APK) - .run(); - - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK); - } - - @Test - public void testInstallSplitOnlyMissingSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFile(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testInstallSplitOnlyWithoutBaseSignature() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles(INSTALLED_BASE_APK); - - new InstallMultiple() - .inheritFrom(TARGET_PACKAGE) - .addFileAndSignature(SPLIT_APK) - .run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_APK_FSV_SIG); - } - - @Test - public void testInstallOnlyDmHasFsvSig() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity( - INSTALLED_BASE_DM, - INSTALLED_SPLIT_DM); - } - - @Test - public void testInstallDmWithoutFsvSig_Base() - throws DeviceNotAvailableException, FileNotFoundException { - InstallMultiple installer = new InstallMultiple() - .addFile(BASE_APK) - .addFile(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM); - if (mDmRequireFsVerity) { - installer.runExpectingFailure(); - } else { - installer.run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM, - INSTALLED_SPLIT_DM_FSV_SIG); - verifyInstalledFilesHaveFsverity(INSTALLED_SPLIT_DM); - } - } - - @Test - public void testInstallDmWithoutFsvSig_Split() - throws DeviceNotAvailableException, FileNotFoundException { - InstallMultiple installer = new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFile(SPLIT_APK_DM); - if (mDmRequireFsVerity) { - installer.runExpectingFailure(); - } else { - installer.run(); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_DM, - INSTALLED_BASE_DM_FSV_SIG, - INSTALLED_SPLIT_APK, - INSTALLED_SPLIT_DM); - verifyInstalledFilesHaveFsverity(INSTALLED_BASE_DM); - } - } - - @Test - public void testInstallSomeApkIsMissingFsvSig_Base() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFile(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .runExpectingFailure(); - } - - @Test - public void testInstallSomeApkIsMissingFsvSig_Split() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .addFileAndSignature(BASE_APK_DM) - .addFileAndSignature(SPLIT_APK) - .addFileAndSignature(SPLIT_APK_DM) - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithFsvSigThenSplitWithout() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFileAndSignature(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles( - INSTALLED_BASE_APK, - INSTALLED_BASE_APK_FSV_SIG); - - new InstallMultiple() - .addFile(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testInstallBaseWithoutFsvSigThenSplitWith() - throws DeviceNotAvailableException, FileNotFoundException { - new InstallMultiple() - .addFile(BASE_APK) - .run(); - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - verifyInstalledFiles(INSTALLED_BASE_APK); - - new InstallMultiple() - .addFileAndSignature(SPLIT_APK) - .runExpectingFailure(); - } - - @Test - public void testFsverityFileIsImmutableAndReadable() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - assertNotNull(getDevice().getAppPackageInfo(TARGET_PACKAGE)); - expectRemoteCommandToFail("echo -n '' >> " + apkPath); - expectRemoteCommandToSucceed("cat " + apkPath + " > /dev/null"); - } - - @Test - public void testFsverityFailToReadModifiedBlockAtFront() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - long apkSize = getFileSizeInBytes(apkPath); - long offsetFirstByte = 0; - - // The first two pages should be both readable at first. - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, offsetFirstByte)); - if (apkSize > offsetFirstByte + FSVERITY_PAGE_SIZE) { - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, - offsetFirstByte + FSVERITY_PAGE_SIZE)); - } - - // Damage the file directly against the block device. - damageFileAgainstBlockDevice(apkPath, offsetFirstByte); - - // Expect actual read from disk to fail but only at damaged page. - expectReadFromBlockDeviceToFail(apkPath, offsetFirstByte); - if (apkSize > offsetFirstByte + FSVERITY_PAGE_SIZE) { - long lastByteOfTheSamePage = - offsetFirstByte % FSVERITY_PAGE_SIZE + FSVERITY_PAGE_SIZE - 1; - assertFalse(BlockDeviceWriter.canReadByte(mDevice, apkPath, lastByteOfTheSamePage)); - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, lastByteOfTheSamePage + 1)); - } - } - - @Test - public void testFsverityFailToReadModifiedBlockAtBack() throws DeviceNotAvailableException { - new InstallMultiple().addFileAndSignature(BASE_APK).run(); - String apkPath = getApkPath(TARGET_PACKAGE); - - long apkSize = getFileSizeInBytes(apkPath); - long offsetOfLastByte = apkSize - 1; - - // The first two pages should be both readable at first. - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, offsetOfLastByte)); - if (offsetOfLastByte - FSVERITY_PAGE_SIZE > 0) { - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, - offsetOfLastByte - FSVERITY_PAGE_SIZE)); - } - - // Damage the file directly against the block device. - damageFileAgainstBlockDevice(apkPath, offsetOfLastByte); - - // Expect actual read from disk to fail but only at damaged page. - expectReadFromBlockDeviceToFail(apkPath, offsetOfLastByte); - if (offsetOfLastByte - FSVERITY_PAGE_SIZE > 0) { - long firstByteOfTheSamePage = offsetOfLastByte - offsetOfLastByte % FSVERITY_PAGE_SIZE; - assertFalse(BlockDeviceWriter.canReadByte(mDevice, apkPath, firstByteOfTheSamePage)); - assertTrue(BlockDeviceWriter.canReadByte(mDevice, apkPath, firstByteOfTheSamePage - 1)); - } - } - - private void verifyInstalledFilesHaveFsverity(String... filenames) - throws DeviceNotAvailableException { - // Verify that all files are protected by fs-verity - String apkPath = getApkPath(TARGET_PACKAGE); - String appDir = apkPath.substring(0, apkPath.lastIndexOf("/")); - long kTargetOffset = 0; - for (String basename : filenames) { - String path = appDir + "/" + basename; - damageFileAgainstBlockDevice(path, kTargetOffset); - - expectReadFromBlockDeviceToFail(path, kTargetOffset); - } - } - - private void expectReadFromBlockDeviceToFail(String readPath, long offset) - throws DeviceNotAvailableException { - // Retry is sometimes needed to pass the test. Package manager may have FD leaks - // (see b/122744005 as example) that prevents the file in question to be evicted - // from filesystem cache. Forcing GC workarounds the problem. - int retry = 5; - for (; retry > 0; retry--) { - BlockDeviceWriter.dropCaches(mDevice); - if (!BlockDeviceWriter.canReadByte(mDevice, readPath, offset)) { - break; - } - try { - String openFiles = expectRemoteCommandToSucceed("lsof " + readPath); - CLog.d("lsof: " + openFiles); - Thread.sleep(1000); - forceGCOnOpenFilesProcess(getOpenFilesPIDs(openFiles)); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - } - assertTrue("Read from " + readPath + " should fail", retry > 0); - } - - /** - * This is a helper method that parses the lsof output to get PIDs of process holding FD. - * Here is an example output of lsof. This method extracts the second columns(PID). - * - * Example lsof output: - * COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME - * .example.app 1063 u0_a38 mem REG 253,6 8599 12826 example.apk - * .example.app 1063 u0_a38 99r REG 253,6 8599 12826 example.apk - */ - private Set<String> getOpenFilesPIDs(String lsof) { - Set<String> openFilesPIDs = new HashSet<>(); - String[] lines = lsof.split("\n"); - for (int i = 1; i < lines.length; i++) { - openFilesPIDs.add(lines[i].split("\\s+")[1]); - } - return openFilesPIDs; - } - - /** - * This is a helper method that forces GC on processes given their PIDs. - * That is to execute shell command "kill -10" on PIDs. - */ - private void forceGCOnOpenFilesProcess(Set<String> openFilesPIDs) - throws DeviceNotAvailableException { - for (String openFilePID : openFilesPIDs) { - mDevice.executeShellV2Command("kill -10 " + openFilePID); - } - } - - private void verifyInstalledFiles(String... filenames) throws DeviceNotAvailableException { - String apkPath = getApkPath(TARGET_PACKAGE); - String appDir = apkPath.substring(0, apkPath.lastIndexOf("/")); - // Exclude directories since we only care about files. - HashSet<String> actualFiles = new HashSet<>(Arrays.asList( - expectRemoteCommandToSucceed("ls -p " + appDir + " | grep -v '/'").split("\n"))); - - HashSet<String> expectedFiles = new HashSet<>(Arrays.asList(filenames)); - assertEquals(expectedFiles, actualFiles); - } - - private void damageFileAgainstBlockDevice(String path, long offsetOfTargetingByte) - throws DeviceNotAvailableException { - assertTrue(path.startsWith("/data/")); - ITestDevice.MountPointInfo mountPoint = mDevice.getMountPointInfo("/data"); - ArrayList<String> args = new ArrayList<>(); - args.add(DAMAGING_EXECUTABLE); - if ("f2fs".equals(mountPoint.type)) { - args.add("--use-f2fs-pinning"); - } - args.add(mountPoint.filesystem); - args.add(path); - args.add(Long.toString(offsetOfTargetingByte)); - expectRemoteCommandToSucceed(String.join(" ", args)); - } - - private String getApkPath(String packageName) throws DeviceNotAvailableException { - String line = expectRemoteCommandToSucceed("pm path " + packageName + " | grep base.apk"); - int index = line.trim().indexOf(":"); - assertTrue(index >= 0); - return line.substring(index + 1); - } - - private long getFileSizeInBytes(String packageName) throws DeviceNotAvailableException { - return Long.parseLong(expectRemoteCommandToSucceed("stat -c '%s' " + packageName).trim()); - } - - private String expectRemoteCommandToSucceed(String cmd) throws DeviceNotAvailableException { - CommandResult result = mDevice.executeShellV2Command(cmd); - assertEquals("`" + cmd + "` failed: " + result.getStderr(), CommandStatus.SUCCESS, - result.getStatus()); - return result.getStdout(); - } - - private void expectRemoteCommandToFail(String cmd) throws DeviceNotAvailableException { - CommandResult result = mDevice.executeShellV2Command(cmd); - assertTrue("Unexpected success from `" + cmd + "`: " + result.getStderr(), - result.getStatus() != CommandStatus.SUCCESS); - } - - private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> { - InstallMultiple() { - super(getDevice(), getBuild()); - } - - InstallMultiple addFileAndSignature(String filename) { - try { - addFile(filename); - addFile(filename + ".fsv_sig"); - } catch (FileNotFoundException e) { - fail("Missing test file: " + e); - } - return this; - } - } -} diff --git a/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java b/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java deleted file mode 100644 index 02e73d157dde..000000000000 --- a/tests/ApkVerityTest/src/com/android/apkverity/BaseInstallMultiple.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2019 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.apkverity; - -import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; -import com.android.tradefed.build.IBuildInfo; -import com.android.tradefed.device.DeviceNotAvailableException; -import com.android.tradefed.device.ITestDevice; - -import junit.framework.TestCase; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Base class for invoking the install-multiple command via ADB. Subclass this for less typing: - * - * <code> private class InstallMultiple extends BaseInstallMultiple<InstallMultiple> { public - * InstallMultiple() { super(getDevice(), null); } } </code> - */ -/*package*/ class BaseInstallMultiple<T extends BaseInstallMultiple<?>> { - - private final ITestDevice mDevice; - private final IBuildInfo mBuild; - - private final List<String> mArgs = new ArrayList<>(); - private final Map<File, String> mFileToRemoteMap = new HashMap<>(); - - /*package*/ BaseInstallMultiple(ITestDevice device, IBuildInfo buildInfo) { - mDevice = device; - mBuild = buildInfo; - addArg("-g"); - } - - T addArg(String arg) { - mArgs.add(arg); - return (T) this; - } - - T addFile(String filename) throws FileNotFoundException { - return addFile(filename, filename); - } - - T addFile(String filename, String remoteName) throws FileNotFoundException { - CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild); - mFileToRemoteMap.put(buildHelper.getTestFile(filename), remoteName); - return (T) this; - } - - T inheritFrom(String packageName) { - addArg("-r"); - addArg("-p " + packageName); - return (T) this; - } - - void run() throws DeviceNotAvailableException { - run(true); - } - - void runExpectingFailure() throws DeviceNotAvailableException { - run(false); - } - - private void run(boolean expectingSuccess) throws DeviceNotAvailableException { - final ITestDevice device = mDevice; - - // Create an install session - final StringBuilder cmd = new StringBuilder(); - cmd.append("pm install-create"); - for (String arg : mArgs) { - cmd.append(' ').append(arg); - } - - String result = device.executeShellCommand(cmd.toString()); - TestCase.assertTrue(result, result.startsWith("Success")); - - final int start = result.lastIndexOf("["); - final int end = result.lastIndexOf("]"); - int sessionId = -1; - try { - if (start != -1 && end != -1 && start < end) { - sessionId = Integer.parseInt(result.substring(start + 1, end)); - } - } catch (NumberFormatException e) { - throw new IllegalStateException("Failed to parse install session: " + result); - } - if (sessionId == -1) { - throw new IllegalStateException("Failed to create install session: " + result); - } - - // Push our files into session. Ideally we'd use stdin streaming, - // but ddmlib doesn't support it yet. - for (final Map.Entry<File, String> entry : mFileToRemoteMap.entrySet()) { - final File file = entry.getKey(); - final String remoteName = entry.getValue(); - final String remotePath = "/data/local/tmp/" + file.getName(); - if (!device.pushFile(file, remotePath)) { - throw new IllegalStateException("Failed to push " + file); - } - - cmd.setLength(0); - cmd.append("pm install-write"); - cmd.append(' ').append(sessionId); - cmd.append(' ').append(remoteName); - cmd.append(' ').append(remotePath); - - result = device.executeShellCommand(cmd.toString()); - TestCase.assertTrue(result, result.startsWith("Success")); - } - - // Everything staged; let's pull trigger - cmd.setLength(0); - cmd.append("pm install-commit"); - cmd.append(' ').append(sessionId); - - result = device.executeShellCommand(cmd.toString()); - if (expectingSuccess) { - TestCase.assertTrue(result, result.contains("Success")); - } else { - TestCase.assertFalse(result, result.contains("Success")); - } - } -} diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm b/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm Binary files differdeleted file mode 100644 index e53a86131366..000000000000 --- a/tests/ApkVerityTest/testdata/ApkVerityTestApp.dm +++ /dev/null diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm b/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm Binary files differdeleted file mode 100644 index 75396f1ba730..000000000000 --- a/tests/ApkVerityTest/testdata/ApkVerityTestAppSplit.dm +++ /dev/null diff --git a/tests/ApkVerityTest/testdata/README.md b/tests/ApkVerityTest/testdata/README.md deleted file mode 100644 index 163cb183a5ad..000000000000 --- a/tests/ApkVerityTest/testdata/README.md +++ /dev/null @@ -1,13 +0,0 @@ -This test only runs on rooted / debuggable device. - -The test tries to install subsets of base.{apk,dm}, split.{apk,dm} and their -corresponding .fsv_sig files (generated by build rule). If installed, the -tests also tries to tamper with the file at absolute disk offset to verify -if fs-verity is effective. - -How to generate dex metadata (.dm) -================================== - - adb shell profman --generate-test-profile=/data/local/tmp/primary.prof - adb pull /data/local/tmp/primary.prof - zip foo.dm primary.prof diff --git a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java index fe2fe0b40891..08430f2f2744 100644 --- a/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java +++ b/tests/BatteryStatsPerfTest/src/com/android/internal/os/BatteryUsageStatsPerfTest.java @@ -159,7 +159,7 @@ public class BatteryUsageStatsPerfTest { private static BatteryUsageStats buildBatteryUsageStats() { final BatteryUsageStats.Builder builder = - new BatteryUsageStats.Builder(new String[]{"FOO"}, true, false) + new BatteryUsageStats.Builder(new String[]{"FOO"}, true, false, 0) .setBatteryCapacity(4000) .setDischargePercentage(20) .setDischargedPowerRange(1000, 2000) diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index 2ccc0fa9e1e7..a2ae56eaeadc 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -95,6 +95,7 @@ java_defaults { "flickertestapplib", "flickerlib", "flickerlib-helpers", + "flickerlib-trace_processor_shell", "platform-test-annotations", "wm-flicker-common-app-helpers", "wm-shell-flicker-utils", diff --git a/tests/FlickerTests/AndroidTestTemplate.xml b/tests/FlickerTests/AndroidTestTemplate.xml index 44a824513b91..878038557cf1 100644 --- a/tests/FlickerTests/AndroidTestTemplate.xml +++ b/tests/FlickerTests/AndroidTestTemplate.xml @@ -61,7 +61,9 @@ <option name="shell-timeout" value="6600s"/> <option name="test-timeout" value="6600s"/> <option name="hidden-api-checks" value="false"/> + <!-- TODO(b/288396763): re-enable when PerfettoListener is fixed <option name="device-listeners" value="android.device.collectors.PerfettoListener"/> + --> <!-- PerfettoListener related arguments --> <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true"/> <option name="instrumentation-arg" diff --git a/tests/FlickerTests/manifests/AndroidManifest.xml b/tests/FlickerTests/manifests/AndroidManifest.xml index 1a34d9ea0f83..6bc7cbe88589 100644 --- a/tests/FlickerTests/manifests/AndroidManifest.xml +++ b/tests/FlickerTests/manifests/AndroidManifest.xml @@ -44,8 +44,12 @@ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS" /> <!-- ActivityOptions.makeCustomTaskAnimation() --> <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" /> - <!-- Allow the test to write directly to /sdcard/ --> - <application android:requestLegacyExternalStorage="true" android:largeHeap="true"> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> + <!-- Allow the test to write directly to /sdcard/ and connect to trace processor --> + <application android:requestLegacyExternalStorage="true" + android:networkSecurityConfig="@xml/network_security_config" + android:largeHeap="true"> <uses-library android:name="android.test.runner"/> <uses-library android:name="androidx.window.extensions" android:required="false"/> diff --git a/tests/FlickerTests/res/xml/network_security_config.xml b/tests/FlickerTests/res/xml/network_security_config.xml new file mode 100644 index 000000000000..4bd9ca049f55 --- /dev/null +++ b/tests/FlickerTests/res/xml/network_security_config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config> diff --git a/tests/ApkVerityTest/Android.bp b/tests/FsVerityTest/Android.bp index f026bea80470..53606a32b185 100644 --- a/tests/ApkVerityTest/Android.bp +++ b/tests/FsVerityTest/Android.bp @@ -22,7 +22,7 @@ package { } java_test_host { - name: "ApkVerityTest", + name: "FsVerityTest", srcs: ["src/**/*.java"], libs: [ "tradefed", @@ -30,8 +30,10 @@ java_test_host { "compatibility-host-util", ], static_libs: [ + "android.security.flags-aconfig-java-host", "block_device_writer_jar", "frameworks-base-hostutils", + "flag-junit-host", ], test_suites: [ "general-tests", @@ -41,14 +43,6 @@ java_test_host { "block_device_writer", ], data: [ - ":ApkVerityTestCertDer", - ":ApkVerityTestApp", - ":ApkVerityTestAppFsvSig", - ":ApkVerityTestAppDm", - ":ApkVerityTestAppDmFsvSig", - ":ApkVerityTestAppSplit", - ":ApkVerityTestAppSplitFsvSig", - ":ApkVerityTestAppSplitDm", - ":ApkVerityTestAppSplitDmFsvSig", + ":FsVerityTestApp", ], } diff --git a/tests/ApkVerityTest/AndroidTest.xml b/tests/FsVerityTest/AndroidTest.xml index 4487cefb4f9c..49cbde0d4611 100644 --- a/tests/ApkVerityTest/AndroidTest.xml +++ b/tests/FsVerityTest/AndroidTest.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<configuration description="APK fs-verity integration/regression test"> +<configuration description="fs-verity end-to-end test"> <option name="test-suite-tag" value="apct" /> <object type="module_controller" class="com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController"> @@ -24,19 +24,9 @@ <!-- This test requires root to write against block device. --> <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" /> - <target_preparer class="com.android.tradefed.targetprep.DeviceSetup"> - <!-- Disable package verifier prevents it holding the target APK's fd that prevents cache - eviction. --> - <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" /> - <option name="restore-settings" value="true" /> - - <!-- Skip in order to prevent reboot that confuses the test flow. --> - <option name="force-skip-system-props" value="true" /> - </target_preparer> - - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="push" value="ApkVerityTestCert.der->/data/local/tmp/ApkVerityTestCert.der" /> + <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup"> + <option name="test-file-name" value="FsVerityTestApp.apk"/> + <option name="cleanup-apks" value="true"/> </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> @@ -48,9 +38,7 @@ <option name="push" value="block_device_writer->/data/local/tmp/block_device_writer" /> </target_preparer> - <!-- Skip on HWASan. TODO(b/232288278): Re-enable --> - <object type="module_controller" class="com.android.tradefed.testtype.suite.module.SkipHWASanModuleController" /> <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" > - <option name="jar" value="ApkVerityTest.jar" /> + <option name="jar" value="FsVerityTest.jar" /> </test> </configuration> diff --git a/tests/ApkVerityTest/ApkVerityTestApp/Android.bp b/tests/FsVerityTest/FsVerityTestApp/Android.bp index adf8f9f9d321..43da3ff9fec1 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/Android.bp +++ b/tests/FsVerityTest/FsVerityTestApp/Android.bp @@ -22,17 +22,8 @@ package { } android_test_helper_app { - name: "ApkVerityTestApp", - manifest: "AndroidManifest.xml", - srcs: ["src/**/*.java"], -} - -android_test_helper_app { - name: "ApkVerityTestAppSplit", - manifest: "feature_split/AndroidManifest.xml", - srcs: ["src/**/*.java"], - aaptflags: [ - "--custom-package com.android.apkverity.feature_x", - "--package-id 0x80", - ], + name: "FsVerityTestApp", + manifest: "AndroidManifest.xml", + srcs: ["src/**/*.java"], + static_libs: ["compatibility-device-util-axt"], } diff --git a/tests/ApkVerityTest/ApkVerityTestApp/AndroidManifest.xml b/tests/FsVerityTest/FsVerityTestApp/AndroidManifest.xml index 0b3ff77c2cdf..42fe49be66d9 100644 --- a/tests/ApkVerityTest/ApkVerityTestApp/AndroidManifest.xml +++ b/tests/FsVerityTest/FsVerityTestApp/AndroidManifest.xml @@ -16,8 +16,12 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.apkverity"> + package="com.android.fsverity"> <application> <activity android:name=".DummyActivity"/> </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.fsverity" + android:label="Helper app of fs-verity test"> + </instrumentation>/> </manifest> diff --git a/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java new file mode 100644 index 000000000000..2ed4fec4a93c --- /dev/null +++ b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fsverity; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertThrows; + +import android.content.Context; +import android.security.FileIntegrityManager; +import android.util.Log; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Test helper that works with the host-side test to set up a test file, and to verify fs-verity + * verification is done expectedly. + */ +public class Helper { + private static final String TAG = "FsVerityTest"; + + private static final String FILENAME = "test.file"; + + private static final long BLOCK_SIZE = 4096; + + @Test + public void prepareTest() throws Exception { + Context context = ApplicationProvider.getApplicationContext(); + android.os.Bundle testArgs = InstrumentationRegistry.getArguments(); + + String basename = testArgs.getString("basename"); + context.deleteFile(basename); + + assertThat(testArgs).isNotNull(); + int fileSize = Integer.parseInt(testArgs.getString("fileSize")); + Log.d(TAG, "Preparing test file with size " + fileSize); + + byte[] bytes = new byte[8192]; + Arrays.fill(bytes, (byte) '1'); + try (FileOutputStream os = context.openFileOutput(basename, Context.MODE_PRIVATE)) { + for (int i = 0; i < fileSize; i += bytes.length) { + if (i + bytes.length > fileSize) { + os.write(bytes, 0, fileSize % bytes.length); + } else { + os.write(bytes); + } + } + } + + // Enable fs-verity + FileIntegrityManager fim = context.getSystemService(FileIntegrityManager.class); + fim.setupFsVerity(context.getFileStreamPath(basename)); + } + + @Test + public void verifyFileRead() throws Exception { + Context context = ApplicationProvider.getApplicationContext(); + + // Collect indices that the backing blocks are supposed to be corrupted. + android.os.Bundle testArgs = InstrumentationRegistry.getArguments(); + assertThat(testArgs).isNotNull(); + String filePath = testArgs.getString("filePath"); + String csv = testArgs.getString("brokenBlockIndicesCsv"); + Log.d(TAG, "brokenBlockIndicesCsv: " + csv); + String[] strings = csv.split(","); + var corrupted = new ArrayList(strings.length); + for (int i = 0; i < strings.length; i++) { + corrupted.add(Integer.parseInt(strings[i])); + } + + // Expect the read to succeed or fail per the prior. + try (var file = new RandomAccessFile(filePath, "r")) { + long total_blocks = (file.length() + BLOCK_SIZE - 1) / BLOCK_SIZE; + for (int i = 0; i < (int) total_blocks; i++) { + file.seek(i * BLOCK_SIZE); + if (corrupted.contains(i)) { + Log.d(TAG, "Expecting read at block #" + i + " to fail"); + assertThrows(IOException.class, () -> file.read()); + } else { + assertThat(file.readByte()).isEqualTo('1'); + } + } + } + } +} diff --git a/tests/ApkVerityTest/OWNERS b/tests/FsVerityTest/OWNERS index d67285ede44a..d67285ede44a 100644 --- a/tests/ApkVerityTest/OWNERS +++ b/tests/FsVerityTest/OWNERS diff --git a/tests/ApkVerityTest/TEST_MAPPING b/tests/FsVerityTest/TEST_MAPPING index 72d96148c69f..39944bed3f60 100644 --- a/tests/ApkVerityTest/TEST_MAPPING +++ b/tests/FsVerityTest/TEST_MAPPING @@ -1,11 +1,11 @@ { - "presubmit": [ + "postsubmit": [ { - "name": "ApkVerityTest" + "name": "FsVerityTest" }, // nextgen test only runs during postsubmit. { - "name": "ApkVerityTest", + "name": "FsVerityTest", "keywords": ["nextgen"] } ] diff --git a/tests/ApkVerityTest/block_device_writer/Android.bp b/tests/FsVerityTest/block_device_writer/Android.bp index 0002447d17f2..0002447d17f2 100644 --- a/tests/ApkVerityTest/block_device_writer/Android.bp +++ b/tests/FsVerityTest/block_device_writer/Android.bp diff --git a/tests/ApkVerityTest/block_device_writer/block_device_writer.cpp b/tests/FsVerityTest/block_device_writer/block_device_writer.cpp index 02dfd732a716..02dfd732a716 100644 --- a/tests/ApkVerityTest/block_device_writer/block_device_writer.cpp +++ b/tests/FsVerityTest/block_device_writer/block_device_writer.cpp diff --git a/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java b/tests/FsVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java index 9be02ec3be86..9be02ec3be86 100644 --- a/tests/ApkVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java +++ b/tests/FsVerityTest/block_device_writer/src/com/android/blockdevicewriter/BlockDeviceWriter.java diff --git a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java new file mode 100644 index 000000000000..be479f205ff2 --- /dev/null +++ b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fsverity; + +import static com.google.common.truth.Truth.assertThat; + +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.annotations.RootPermissionTest; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.host.HostFlagsValueProvider; +import android.security.Flags; + +import com.android.blockdevicewriter.BlockDeviceWriter; +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; +import com.android.tradefed.testtype.junit4.DeviceTestRunOptions; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This test verifies fs-verity works end-to-end. There is a corresponding helper app. + * + * <p>The helper app uses a FileIntegrityManager API to enable fs-verity to a file. The host test + * here * tampers with the file's backing storage, then tells the helper app to read and expect + * success/failure on read. + * + * <p>In order to make sure a block of the file is readable only if the underlying block on disk + * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical + * address against the block device. + */ +@RootPermissionTest +@RunWith(DeviceJUnit4ClassRunner.class) +@RequiresFlagsEnabled(Flags.FLAG_FSVERITY_API) +public class FsVerityHostTest extends BaseHostJUnit4Test { + private static final String TARGET_PACKAGE = "com.android.fsverity"; + + private static final String BASENAME = "test.file"; + private static final String TARGET_PATH = "/data/data/" + TARGET_PACKAGE + "/files/" + BASENAME; + + @Rule + public final CheckFlagsRule mCheckFlagsRule = + HostFlagsValueProvider.createCheckFlagsRule(this::getDevice); + + @Test + public void testFsVeritySmallFile() throws Exception { + prepareTest(10000); + + ITestDevice device = getDevice(); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 0); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 8192); + BlockDeviceWriter.dropCaches(device); + + verifyRead(TARGET_PATH, "0,2"); + } + + @Test + public void testFsVerityLargerFileWithOneMoreMerkleTreeLevel() throws Exception { + prepareTest(128 * 4096 + 1); + + ITestDevice device = getDevice(); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 4096); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 100 * 4096); + BlockDeviceWriter.damageFileAgainstBlockDevice(device, TARGET_PATH, 128 * 4096 + 1); + BlockDeviceWriter.dropCaches(device); + + verifyRead(TARGET_PATH, "1,100,128"); + } + + private void prepareTest(int fileSize) throws Exception { + DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE); + options.setTestClassName(TARGET_PACKAGE + ".Helper"); + options.setTestMethodName("prepareTest"); + options.addInstrumentationArg("basename", BASENAME); + options.addInstrumentationArg("fileSize", String.valueOf(fileSize)); + assertThat(runDeviceTests(options)).isTrue(); + } + + private void verifyRead(String path, String indicesCsv) throws Exception { + DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE); + options.setTestClassName(TARGET_PACKAGE + ".Helper"); + options.setTestMethodName("verifyFileRead"); + options.addInstrumentationArg("brokenBlockIndicesCsv", indicesCsv); + options.addInstrumentationArg("filePath", TARGET_PATH); + assertThat(runDeviceTests(options)).isTrue(); + } +} diff --git a/tests/ApkVerityTest/testdata/Android.bp b/tests/FsVerityTest/testdata/Android.bp index ccfc4c99a347..2d578d36423d 100644 --- a/tests/ApkVerityTest/testdata/Android.bp +++ b/tests/FsVerityTest/testdata/Android.bp @@ -37,51 +37,3 @@ filegroup { name: "ApkVerityTestCertDer", srcs: ["ApkVerityTestCert.der"], } - -filegroup { - name: "ApkVerityTestAppDm", - srcs: ["ApkVerityTestApp.dm"], -} - -filegroup { - name: "ApkVerityTestAppSplitDm", - srcs: ["ApkVerityTestAppSplit.dm"], -} - -genrule_defaults { - name: "apk_verity_sig_gen_default", - tools: ["fsverity"], - tool_files: [":ApkVerityTestKeyPem", ":ApkVerityTestCertPem"], - cmd: "$(location fsverity) sign $(in) $(out) " + - "--key=$(location :ApkVerityTestKeyPem) " + - "--cert=$(location :ApkVerityTestCertPem) " + - "> /dev/null", -} - -genrule { - name: "ApkVerityTestAppFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestApp"], - out: ["ApkVerityTestApp.apk.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppDmFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppDm"], - out: ["ApkVerityTestApp.dm.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppSplitFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppSplit"], - out: ["ApkVerityTestAppSplit.apk.fsv_sig"], -} - -genrule { - name: "ApkVerityTestAppSplitDmFsvSig", - defaults: ["apk_verity_sig_gen_default"], - srcs: [":ApkVerityTestAppSplitDm"], - out: ["ApkVerityTestAppSplit.dm.fsv_sig"], -} diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestCert.der b/tests/FsVerityTest/testdata/ApkVerityTestCert.der Binary files differindex fe9029b53aa1..fe9029b53aa1 100644 --- a/tests/ApkVerityTest/testdata/ApkVerityTestCert.der +++ b/tests/FsVerityTest/testdata/ApkVerityTestCert.der diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestCert.pem b/tests/FsVerityTest/testdata/ApkVerityTestCert.pem index 6c0b7b1f635a..6c0b7b1f635a 100644 --- a/tests/ApkVerityTest/testdata/ApkVerityTestCert.pem +++ b/tests/FsVerityTest/testdata/ApkVerityTestCert.pem diff --git a/tests/ApkVerityTest/testdata/ApkVerityTestKey.pem b/tests/FsVerityTest/testdata/ApkVerityTestKey.pem index f0746c162421..f0746c162421 100644 --- a/tests/ApkVerityTest/testdata/ApkVerityTestKey.pem +++ b/tests/FsVerityTest/testdata/ApkVerityTestKey.pem diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp index dc75f00e7cdc..38313f85c31d 100644 --- a/tests/SurfaceViewBufferTests/Android.bp +++ b/tests/SurfaceViewBufferTests/Android.bp @@ -23,7 +23,10 @@ package { android_test { name: "SurfaceViewBufferTests", - srcs: ["**/*.java","**/*.kt"], + srcs: [ + "**/*.java", + "**/*.kt", + ], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, @@ -41,6 +44,7 @@ android_test { "kotlin-stdlib", "kotlinx-coroutines-android", "flickerlib", + "flickerlib-trace_processor_shell", "truth-prebuilt", "cts-wm-util", "CtsSurfaceValidatorLib", @@ -60,7 +64,7 @@ cc_library_shared { "libandroid", ], include_dirs: [ - "system/core/include" + "system/core/include", ], stl: "libc++_static", cflags: [ diff --git a/tests/SurfaceViewBufferTests/AndroidManifest.xml b/tests/SurfaceViewBufferTests/AndroidManifest.xml index 78415e8641eb..798c67a320ce 100644 --- a/tests/SurfaceViewBufferTests/AndroidManifest.xml +++ b/tests/SurfaceViewBufferTests/AndroidManifest.xml @@ -29,9 +29,12 @@ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- Save failed test bitmap images !--> <uses-permission android:name="android.Manifest.permission.WRITE_EXTERNAL_STORAGE"/> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="false" - android:supportsRtl="true"> + android:supportsRtl="true" + android:networkSecurityConfig="@xml/network_security_config"> <activity android:name=".MainActivity" android:taskAffinity="com.android.test.MainActivity" android:theme="@style/AppTheme" diff --git a/tests/SurfaceViewBufferTests/res/xml/network_security_config.xml b/tests/SurfaceViewBufferTests/res/xml/network_security_config.xml new file mode 100644 index 000000000000..4bd9ca049f55 --- /dev/null +++ b/tests/SurfaceViewBufferTests/res/xml/network_security_config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config> diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt index a38019d67376..b03b7335b08b 100644 --- a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt +++ b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceTracingTestBase.kt @@ -21,11 +21,9 @@ import android.graphics.Color import android.graphics.Rect import android.util.Log import androidx.test.ext.junit.rules.ActivityScenarioRule -import android.tools.common.flicker.subject.layers.LayerSubject import android.tools.common.traces.surfaceflinger.LayersTrace -import android.tools.device.traces.io.ResultWriter -import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor import android.tools.device.traces.monitors.withSFTracing +import android.tools.device.traces.monitors.PerfettoTraceMonitor import junit.framework.Assert import org.junit.After import org.junit.Before @@ -33,6 +31,7 @@ import org.junit.Rule import java.io.FileOutputStream import java.io.IOException import java.util.concurrent.CountDownLatch +import perfetto.protos.PerfettoConfig.SurfaceFlingerLayersConfig open class SurfaceTracingTestBase(useBlastAdapter: Boolean) : SurfaceViewBufferTestBase(useBlastAdapter) { @@ -43,7 +42,7 @@ open class SurfaceTracingTestBase(useBlastAdapter: Boolean) : @Before override fun setup() { super.setup() - stopLayerTrace() + PerfettoTraceMonitor.stopAllSessions() addSurfaceView() } @@ -83,10 +82,6 @@ open class SurfaceTracingTestBase(useBlastAdapter: Boolean) : instrumentation.waitForIdleSync() } - private fun stopLayerTrace() { - LayersTraceMonitor().stop(ResultWriter()) - } - fun checkPixels(bounds: Rect, @ColorInt color: Int) { val screenshot = instrumentation.getUiAutomation().takeScreenshot() val pixels = IntArray(screenshot.width * screenshot.height) @@ -106,14 +101,19 @@ open class SurfaceTracingTestBase(useBlastAdapter: Boolean) : Log.e("SurfaceViewBufferTests", "Error writing bitmap to file", e) } } - Assert.assertEquals("Checking $bounds found mismatch $i,$j", - Color.valueOf(color), Color.valueOf(actualColor)) + Assert.assertEquals( + "Checking $bounds found mismatch $i,$j", + Color.valueOf(color), + Color.valueOf(actualColor) + ) } } } private companion object { - private const val TRACE_FLAGS = - (1 shl 0) or (1 shl 5) or (1 shl 6) // TRACE_CRITICAL | TRACE_BUFFERS | TRACE_SYNC + private val TRACE_FLAGS = listOf( + SurfaceFlingerLayersConfig.TraceFlag.TRACE_FLAG_BUFFERS, + SurfaceFlingerLayersConfig.TraceFlag.TRACE_FLAG_VIRTUAL_DISPLAYS, + ) } }
\ No newline at end of file diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp index 9b72d359aae6..bf12f423f145 100644 --- a/tests/TaskOrganizerTest/Android.bp +++ b/tests/TaskOrganizerTest/Android.bp @@ -25,7 +25,10 @@ package { android_test { name: "TaskOrganizerTest", - srcs: ["**/*.java","**/*.kt"], + srcs: [ + "**/*.java", + "**/*.kt", + ], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, @@ -39,6 +42,7 @@ android_test { "kotlin-stdlib", "kotlinx-coroutines-android", "flickerlib", + "flickerlib-trace_processor_shell", "truth-prebuilt", ], -}
\ No newline at end of file +} diff --git a/tests/TaskOrganizerTest/AndroidManifest.xml b/tests/TaskOrganizerTest/AndroidManifest.xml index 1f1bd3ef7d81..cbeb246eb86c 100644 --- a/tests/TaskOrganizerTest/AndroidManifest.xml +++ b/tests/TaskOrganizerTest/AndroidManifest.xml @@ -16,9 +16,11 @@ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/> <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> + <!-- Allow the test to connect to perfetto trace processor --> + <uses-permission android:name="android.permission.INTERNET"/> <!-- Enable / Disable tracing !--> <uses-permission android:name="android.permission.DUMP" /> - <application> + <application android:networkSecurityConfig="@xml/network_security_config"> <activity android:name="TaskOrganizerMultiWindowTest" android:label="TaskOrganizer MW Test" android:exported="true" diff --git a/tests/TaskOrganizerTest/res/xml/network_security_config.xml b/tests/TaskOrganizerTest/res/xml/network_security_config.xml new file mode 100644 index 000000000000..e450a993da28 --- /dev/null +++ b/tests/TaskOrganizerTest/res/xml/network_security_config.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +~ Copyright (C) 2023 The Android Open Source Project +~ +~ Licensed under the Apache License, Version 2.0 (the "License"); +~ you may not use this file except in compliance with the License. +~ You may obtain a copy of the License at +~ +~ http://www.apache.org/licenses/LICENSE-2.0 +~ +~ Unless required by applicable law or agreed to in writing, software +~ distributed under the License is distributed on an "AS IS" BASIS, +~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +~ See the License for the specific language governing permissions and +~ limitations under the License. +--> +<network-security-config> + <domain-config cleartextTrafficPermitted="true"> + <domain includeSubdomains="true">localhost</domain> + </domain-config> +</network-security-config>
\ No newline at end of file diff --git a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt index 6f4f7b13af66..2c7905d552f1 100644 --- a/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt +++ b/tests/TaskOrganizerTest/src/com/android/test/taskembed/ResizeTasksSyncTest.kt @@ -22,8 +22,6 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.runner.AndroidJUnit4 import android.tools.common.datatypes.Size import android.tools.common.flicker.subject.layers.LayersTraceSubject -import android.tools.device.traces.io.ResultWriter -import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor import android.tools.device.traces.monitors.withSFTracing import org.junit.After import org.junit.Before @@ -41,16 +39,13 @@ class ResizeTasksSyncTest { @get:Rule var scenarioRule: ActivityScenarioRule<TaskOrganizerMultiWindowTest> = ActivityScenarioRule<TaskOrganizerMultiWindowTest>( - TaskOrganizerMultiWindowTest::class.java) + TaskOrganizerMultiWindowTest::class.java + ) protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation() @Before fun setup() { - val monitor = LayersTraceMonitor() - if (monitor.isEnabled) { - monitor.stop(ResultWriter()) - } val firstTaskBounds = Rect(0, 0, 1080, 1000) val secondTaskBounds = Rect(0, 1000, 1080, 2000) @@ -71,7 +66,7 @@ class ResizeTasksSyncTest { val firstBounds = Rect(0, 0, 1080, 800) val secondBounds = Rect(0, 1000, 1080, 1800) - val trace = withSFTracing(TRACE_FLAGS) { + val trace = withSFTracing() { lateinit var resizeReadyLatch: CountDownLatch scenarioRule.getScenario().onActivity { resizeReadyLatch = it.resizeTaskView(firstBounds, secondBounds) @@ -106,7 +101,6 @@ class ResizeTasksSyncTest { } companion object { - private const val TRACE_FLAGS = 0x1 // TRACE_CRITICAL private const val FIRST_ACTIVITY = "Activity1" private const val SECOND_ACTIVITY = "Activity2" } diff --git a/tools/hoststubgen/OWNERS b/tools/hoststubgen/OWNERS new file mode 100644 index 000000000000..a8c5321307d1 --- /dev/null +++ b/tools/hoststubgen/OWNERS @@ -0,0 +1,3 @@ +omakoto@google.com +jsharkey@google.com +jaggies@google.com |